@@ -1283,6 +1283,278 @@ partial class MyViewModel
1283
1283
VerifyGenerateSources ( source , new [ ] { new RelayCommandGenerator ( ) } , ( "MyApp.MyViewModel.Test.g.cs" , result ) ) ;
1284
1284
}
1285
1285
1286
+ // See https://github.com/CommunityToolkit/dotnet/issues/681
1287
+ [ TestMethod ]
1288
+ public void ObservablePropertyWithForwardedAttributesWithEnumWithNegativeValue_WorksCorrectly ( )
1289
+ {
1290
+ string source = """
1291
+ using System.ComponentModel;
1292
+ using CommunityToolkit.Mvvm.ComponentModel;
1293
+
1294
+ #nullable enable
1295
+
1296
+ namespace MyApp;
1297
+
1298
+ partial class MyViewModel : ObservableObject
1299
+ {
1300
+ [ObservableProperty]
1301
+ [property: DefaultValue(NegativeEnum1.Problem)]
1302
+ [property: DefaultValue(NegativeEnum2.Problem)]
1303
+ [property: DefaultValue(NegativeEnum3.Problem)]
1304
+ [property: DefaultValue(NegativeEnum4.Problem)]
1305
+ private object? a;
1306
+ }
1307
+
1308
+ public class DefaultValueAttribute : Attribute
1309
+ {
1310
+ public DefaultValueAttribute(object value)
1311
+ {
1312
+ }
1313
+ }
1314
+
1315
+ public enum NegativeEnum1
1316
+ {
1317
+ Problem = -1073741824,
1318
+ OK = 0
1319
+ }
1320
+
1321
+ public enum NegativeEnum2 : long
1322
+ {
1323
+ Problem = long.MinValue,
1324
+ OK = 0
1325
+ }
1326
+
1327
+ public enum NegativeEnum3 : short
1328
+ {
1329
+ Problem = -1234,
1330
+ OK = 0
1331
+ }
1332
+
1333
+ public enum NegativeEnum4 : sbyte
1334
+ {
1335
+ Problem = -1,
1336
+ OK = 0
1337
+ }
1338
+ """ ;
1339
+
1340
+ string result = """
1341
+ // <auto-generated/>
1342
+ #pragma warning disable
1343
+ #nullable enable
1344
+ namespace MyApp
1345
+ {
1346
+ /// <inheritdoc/>
1347
+ partial class MyViewModel
1348
+ {
1349
+ /// <inheritdoc cref="a"/>
1350
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1351
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1352
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)-1073741824)]
1353
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)-9223372036854775808)]
1354
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)-1234)]
1355
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)-1)]
1356
+ public object? A
1357
+ {
1358
+ get => a;
1359
+ set
1360
+ {
1361
+ if (!global::System.Collections.Generic.EqualityComparer<object?>.Default.Equals(a, value))
1362
+ {
1363
+ OnAChanging(value);
1364
+ OnAChanging(default, value);
1365
+ OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.A);
1366
+ a = value;
1367
+ OnAChanged(value);
1368
+ OnAChanged(default, value);
1369
+ OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.A);
1370
+ }
1371
+ }
1372
+ }
1373
+
1374
+ /// <summary>Executes the logic for when <see cref="A"/> is changing.</summary>
1375
+ /// <param name="value">The new property value being set.</param>
1376
+ /// <remarks>This method is invoked right before the value of <see cref="A"/> is changed.</remarks>
1377
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1378
+ partial void OnAChanging(object? value);
1379
+ /// <summary>Executes the logic for when <see cref="A"/> is changing.</summary>
1380
+ /// <param name="oldValue">The previous property value that is being replaced.</param>
1381
+ /// <param name="newValue">The new property value being set.</param>
1382
+ /// <remarks>This method is invoked right before the value of <see cref="A"/> is changed.</remarks>
1383
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1384
+ partial void OnAChanging(object? oldValue, object? newValue);
1385
+ /// <summary>Executes the logic for when <see cref="A"/> just changed.</summary>
1386
+ /// <param name="value">The new property value that was set.</param>
1387
+ /// <remarks>This method is invoked right after the value of <see cref="A"/> is changed.</remarks>
1388
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1389
+ partial void OnAChanged(object? value);
1390
+ /// <summary>Executes the logic for when <see cref="A"/> just changed.</summary>
1391
+ /// <param name="oldValue">The previous property value that was replaced.</param>
1392
+ /// <param name="newValue">The new property value that was set.</param>
1393
+ /// <remarks>This method is invoked right after the value of <see cref="A"/> is changed.</remarks>
1394
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1395
+ partial void OnAChanged(object? oldValue, object? newValue);
1396
+ }
1397
+ }
1398
+ """ ;
1399
+
1400
+ VerifyGenerateSources ( source , new [ ] { new ObservablePropertyGenerator ( ) } , ( "MyApp.MyViewModel.g.cs" , result ) ) ;
1401
+ }
1402
+
1403
+ [ TestMethod ]
1404
+ public void ObservablePropertyWithForwardedAttributesWithEnumWithCombinedValues_WorksCorrectly ( )
1405
+ {
1406
+ string source = """
1407
+ using System.ComponentModel;
1408
+ using CommunityToolkit.Mvvm.ComponentModel;
1409
+
1410
+ #nullable enable
1411
+
1412
+ namespace MyApp;
1413
+
1414
+ partial class MyViewModel : ObservableObject
1415
+ {
1416
+ [ObservableProperty]
1417
+ [property: DefaultValue(NegativeEnum1.A)]
1418
+ [property: DefaultValue(NegativeEnum1.B)]
1419
+ [property: DefaultValue((NegativeEnum1)42)]
1420
+ [property: DefaultValue((NegativeEnum1)OtherClass.MyNumber)]
1421
+ [property: DefaultValue(OtherClass.MyEnumValue)]
1422
+ [property: DefaultValue(NegativeEnum2.A)]
1423
+ [property: DefaultValue(NegativeEnum2.B)]
1424
+ [property: DefaultValue((NegativeEnum2)42)]
1425
+ [property: DefaultValue((NegativeEnum2)OtherClass.MyNumber)]
1426
+ [property: DefaultValue((NegativeEnum2)(int)OtherClass.MyEnumValue)]
1427
+ [property: DefaultValue(NegativeEnum3.A)]
1428
+ [property: DefaultValue(NegativeEnum3.B)]
1429
+ [property: DefaultValue((NegativeEnum3)42)]
1430
+ [property: DefaultValue((NegativeEnum3)OtherClass.MyNumber)]
1431
+ [property: DefaultValue((NegativeEnum3)(int)OtherClass.MyEnumValue)]
1432
+ [property: DefaultValue(NegativeEnum4.A)]
1433
+ [property: DefaultValue(NegativeEnum4.B)]
1434
+ [property: DefaultValue((NegativeEnum4)42)]
1435
+ [property: DefaultValue((NegativeEnum4)unchecked((sbyte)OtherClass.MyNumber))]
1436
+ [property: DefaultValue((NegativeEnum4)(int)OtherClass.MyEnumValue)]
1437
+ private object? a;
1438
+ }
1439
+
1440
+ public static class OtherClass
1441
+ {
1442
+ public const int MyNumber = 456;
1443
+ public const NegativeEnum1 MyEnumValue = NegativeEnum1.C;
1444
+ }
1445
+
1446
+ public class DefaultValueAttribute : Attribute
1447
+ {
1448
+ public DefaultValueAttribute(object value)
1449
+ {
1450
+ }
1451
+ }
1452
+
1453
+ public enum NegativeEnum1
1454
+ {
1455
+ A = 0,
1456
+ B = -1073741824,
1457
+ C = 123
1458
+ }
1459
+
1460
+ public enum NegativeEnum2 : long
1461
+ {
1462
+ A = 0,
1463
+ B = long.MinValue
1464
+ }
1465
+
1466
+ public enum NegativeEnum3 : short
1467
+ {
1468
+ A = 1,
1469
+ B = -1234
1470
+ }
1471
+
1472
+ public enum NegativeEnum4 : sbyte
1473
+ {
1474
+ A = 1,
1475
+ B = -1
1476
+ }
1477
+ """ ;
1478
+
1479
+ string result = """
1480
+ // <auto-generated/>
1481
+ #pragma warning disable
1482
+ #nullable enable
1483
+ namespace MyApp
1484
+ {
1485
+ /// <inheritdoc/>
1486
+ partial class MyViewModel
1487
+ {
1488
+ /// <inheritdoc cref="a"/>
1489
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1490
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1491
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)0)]
1492
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)-1073741824)]
1493
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)42)]
1494
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)456)]
1495
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)123)]
1496
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)0)]
1497
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)-9223372036854775808)]
1498
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)42)]
1499
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)456)]
1500
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)123)]
1501
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)1)]
1502
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)-1234)]
1503
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)42)]
1504
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)456)]
1505
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)123)]
1506
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)1)]
1507
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)-1)]
1508
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)42)]
1509
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)-56)]
1510
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)123)]
1511
+ public object? A
1512
+ {
1513
+ get => a;
1514
+ set
1515
+ {
1516
+ if (!global::System.Collections.Generic.EqualityComparer<object?>.Default.Equals(a, value))
1517
+ {
1518
+ OnAChanging(value);
1519
+ OnAChanging(default, value);
1520
+ OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.A);
1521
+ a = value;
1522
+ OnAChanged(value);
1523
+ OnAChanged(default, value);
1524
+ OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.A);
1525
+ }
1526
+ }
1527
+ }
1528
+
1529
+ /// <summary>Executes the logic for when <see cref="A"/> is changing.</summary>
1530
+ /// <param name="value">The new property value being set.</param>
1531
+ /// <remarks>This method is invoked right before the value of <see cref="A"/> is changed.</remarks>
1532
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1533
+ partial void OnAChanging(object? value);
1534
+ /// <summary>Executes the logic for when <see cref="A"/> is changing.</summary>
1535
+ /// <param name="oldValue">The previous property value that is being replaced.</param>
1536
+ /// <param name="newValue">The new property value being set.</param>
1537
+ /// <remarks>This method is invoked right before the value of <see cref="A"/> is changed.</remarks>
1538
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1539
+ partial void OnAChanging(object? oldValue, object? newValue);
1540
+ /// <summary>Executes the logic for when <see cref="A"/> just changed.</summary>
1541
+ /// <param name="value">The new property value that was set.</param>
1542
+ /// <remarks>This method is invoked right after the value of <see cref="A"/> is changed.</remarks>
1543
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1544
+ partial void OnAChanged(object? value);
1545
+ /// <summary>Executes the logic for when <see cref="A"/> just changed.</summary>
1546
+ /// <param name="oldValue">The previous property value that was replaced.</param>
1547
+ /// <param name="newValue">The new property value that was set.</param>
1548
+ /// <remarks>This method is invoked right after the value of <see cref="A"/> is changed.</remarks>
1549
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
1550
+ partial void OnAChanged(object? oldValue, object? newValue);
1551
+ }
1552
+ }
1553
+ """ ;
1554
+
1555
+ VerifyGenerateSources ( source , new [ ] { new ObservablePropertyGenerator ( ) } , ( "MyApp.MyViewModel.g.cs" , result ) ) ;
1556
+ }
1557
+
1286
1558
// See https://github.com/CommunityToolkit/dotnet/issues/632
1287
1559
[ TestMethod ]
1288
1560
public void RelayCommandMethodWithPartialDeclarations_TriggersCorrectly ( )
@@ -1450,6 +1722,96 @@ partial class MyViewModel
1450
1722
VerifyGenerateSources ( source , new [ ] { new RelayCommandGenerator ( ) } , ( "MyApp.MyViewModel.Test1.g.cs" , result1 ) , ( "MyApp.MyViewModel.Test2.g.cs" , result2 ) ) ;
1451
1723
}
1452
1724
1725
+ // See https://github.com/CommunityToolkit/dotnet/issues/681
1726
+ [ TestMethod ]
1727
+ public void RelayCommandMethodWithForwardedAttributesWithEnumValues_WorksCorrectly ( )
1728
+ {
1729
+ string source = """
1730
+ using CommunityToolkit.Mvvm.Input;
1731
+
1732
+ #nullable enable
1733
+
1734
+ namespace MyApp;
1735
+
1736
+ partial class MyViewModel
1737
+ {
1738
+ [RelayCommand]
1739
+ [field: DefaultValue(NegativeEnum1.Problem)]
1740
+ [field: DefaultValue(NegativeEnum2.Problem)]
1741
+ [field: DefaultValue(NegativeEnum3.Problem)]
1742
+ [field: DefaultValue(NegativeEnum4.Problem)]
1743
+ [property: DefaultValue(NegativeEnum1.Problem)]
1744
+ [property: DefaultValue(NegativeEnum2.Problem)]
1745
+ [property: DefaultValue(NegativeEnum3.Problem)]
1746
+ [property: DefaultValue(NegativeEnum4.Problem)]
1747
+ private void Test()
1748
+ {
1749
+ }
1750
+ }
1751
+
1752
+ public class DefaultValueAttribute : Attribute
1753
+ {
1754
+ public DefaultValueAttribute(object value)
1755
+ {
1756
+ }
1757
+ }
1758
+
1759
+ public enum NegativeEnum1
1760
+ {
1761
+ Problem = -1073741824,
1762
+ OK = 0
1763
+ }
1764
+
1765
+ public enum NegativeEnum2 : long
1766
+ {
1767
+ Problem = long.MinValue,
1768
+ OK = 0
1769
+ }
1770
+
1771
+ public enum NegativeEnum3 : short
1772
+ {
1773
+ Problem = -1234,
1774
+ OK = 0
1775
+ }
1776
+
1777
+ public enum NegativeEnum4 : sbyte
1778
+ {
1779
+ Problem = -1,
1780
+ OK = 0
1781
+ }
1782
+ """ ;
1783
+
1784
+ string result = """
1785
+ // <auto-generated/>
1786
+ #pragma warning disable
1787
+ #nullable enable
1788
+ namespace MyApp
1789
+ {
1790
+ /// <inheritdoc/>
1791
+ partial class MyViewModel
1792
+ {
1793
+ /// <summary>The backing field for <see cref="TestCommand"/>.</summary>
1794
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.RelayCommandGenerator", "8.2.0.0")]
1795
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)-1073741824)]
1796
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)-9223372036854775808)]
1797
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)-1234)]
1798
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)-1)]
1799
+ private global::CommunityToolkit.Mvvm.Input.RelayCommand? testCommand;
1800
+ /// <summary>Gets an <see cref="global::CommunityToolkit.Mvvm.Input.IRelayCommand"/> instance wrapping <see cref="Test"/>.</summary>
1801
+ [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.RelayCommandGenerator", "8.2.0.0")]
1802
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1803
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum1)-1073741824)]
1804
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum2)-9223372036854775808)]
1805
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum3)-1234)]
1806
+ [global::MyApp.DefaultValueAttribute((global::MyApp.NegativeEnum4)-1)]
1807
+ public global::CommunityToolkit.Mvvm.Input.IRelayCommand TestCommand => testCommand ??= new global::CommunityToolkit.Mvvm.Input.RelayCommand(new global::System.Action(Test));
1808
+ }
1809
+ }
1810
+ """ ;
1811
+
1812
+ VerifyGenerateSources ( source , new [ ] { new RelayCommandGenerator ( ) } , ( "MyApp.MyViewModel.Test.g.cs" , result ) ) ;
1813
+ }
1814
+
1453
1815
[ TestMethod ]
1454
1816
public void ObservablePropertyWithinGenericAndNestedTypes ( )
1455
1817
{
0 commit comments