Skip to content

Commit 73e85b4

Browse files
authored
Merge pull request #249 from CommunityToolkit/dev/culture-invariant-generators
Make source generators culture invariant
2 parents df07309 + 9f951c2 commit 73e85b4

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System.Collections.Immutable;
66
using System.ComponentModel;
7+
using System.Globalization;
78
using System.Linq;
89
using CommunityToolkit.Mvvm.SourceGenerators.ComponentModel.Models;
910
using CommunityToolkit.Mvvm.SourceGenerators.Diagnostics;
@@ -756,7 +757,7 @@ public static string GetGeneratedPropertyName(IFieldSymbol fieldSymbol)
756757
propertyName = propertyName.TrimStart('_');
757758
}
758759

759-
return $"{char.ToUpper(propertyName[0])}{propertyName.Substring(1)}";
760+
return $"{char.ToUpper(propertyName[0], CultureInfo.InvariantCulture)}{propertyName.Substring(1)}";
760761
}
761762
}
762763
}

CommunityToolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.Execute.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Immutable;
77
using System.Diagnostics.CodeAnalysis;
8+
using System.Globalization;
89
using System.Linq;
910
using CommunityToolkit.Mvvm.SourceGenerators.Diagnostics;
1011
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
@@ -358,7 +359,7 @@ public static (string FieldName, string PropertyName) GetGeneratedFieldAndProper
358359

359360
propertyName += "Command";
360361

361-
string fieldName = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1)}";
362+
string fieldName = $"{char.ToLower(propertyName[0], CultureInfo.InvariantCulture)}{propertyName.Substring(1)}";
362363

363364
return (fieldName, propertyName);
364365
}

tests/CommunityToolkit.Mvvm.UnitTests/Test_ICommandAttribute.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,16 @@ public async Task Test_ICommandAttribute_TaskOfTReturns()
462462
Assert.AreEqual("Hello world", await (Task<string>)greetWithParamAndCommandTask);
463463
}
464464

465+
// See https://github.com/CommunityToolkit/dotnet/issues/230
466+
[TestMethod]
467+
public void Test_ICommandAttribute_CultureAwareCommandName()
468+
{
469+
ModelWithCultureAwareCommandName model = new();
470+
471+
// This just needs to ensure it compiles, really
472+
model.InitializeCommand.Execute(null);
473+
}
474+
465475
#region Region
466476
public class Region
467477
{
@@ -787,4 +797,13 @@ private async Task<string> GreetWithParamAndTokenAsync(object _, CancellationTok
787797
return "Hello world";
788798
}
789799
}
800+
801+
partial class ModelWithCultureAwareCommandName
802+
{
803+
// This starts with "I" to ensure it's converted to lowercase using invariant culture
804+
[ICommand]
805+
private void Initialize()
806+
{
807+
}
808+
}
790809
}

tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservablePropertyAttribute.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,23 @@ public void Test_ObservableProperty_WithBaseViewModelWithObservableObjectAttribu
591591
CollectionAssert.AreEqual(new[] { nameof(model.MyProperty), nameof(model.OtherProperty) }, propertyNames);
592592
}
593593

594+
// See https://github.com/CommunityToolkit/dotnet/issues/230
595+
[TestMethod]
596+
public void Test_ObservableProperty_ModelWithCultureAwarePropertyName()
597+
{
598+
ModelWithCultureAwarePropertyName model = new();
599+
600+
List<string?> propertyNames = new();
601+
602+
model.PropertyChanged += (s, e) => propertyNames.Add(e.PropertyName);
603+
604+
model.InputFolder = 42;
605+
606+
Assert.AreEqual(model.InputFolder, 42);
607+
608+
CollectionAssert.AreEqual(new[] { nameof(model.InputFolder) }, propertyNames);
609+
}
610+
594611
public abstract partial class BaseViewModel : ObservableObject
595612
{
596613
public string? Content { get; set; }
@@ -965,4 +982,13 @@ partial class ModelWithMultipleGenericParameters<T, U> : ObservableObject, IValu
965982
[ObservableProperty]
966983
private List<T>? list;
967984
}
985+
986+
[ObservableObject]
987+
partial class ModelWithCultureAwarePropertyName
988+
{
989+
// This starts with "i" as it's one of the characters that can change when converted to uppercase.
990+
// For instance, when using the Turkish language pack, this would become "İnputFolder" if done wrong.
991+
[ObservableProperty]
992+
private int _inputFolder;
993+
}
968994
}

0 commit comments

Comments
 (0)