Skip to content

Commit f561a05

Browse files
authored
Initial changes for GetLocaleInfoString (#81470)
Initial changes for globalization hybrid mode. Implemented GetLocaleInfoStringName and GetLocaleNameNative for osx platforms.
1 parent 93e91df commit f561a05

File tree

18 files changed

+320
-3
lines changed

18 files changed

+320
-3
lines changed

docs/workflow/trimming/feature-switches.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ configurations but their defaults might vary as any SDK can set the defaults dif
1313
| EnableUnsafeBinaryFormatterSerialization | System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization | BinaryFormatter serialization support is trimmed when set to false |
1414
| EventSourceSupport | System.Diagnostics.Tracing.EventSource.IsSupported | Any EventSource related code or logic is trimmed when set to false |
1515
| InvariantGlobalization | System.Globalization.Invariant | All globalization specific code and data is trimmed when set to true |
16+
| HybridGlobalization | System.Globalization.Hybrid | Loading ICU + native implementations |
1617
| PredefinedCulturesOnly | System.Globalization.PredefinedCulturesOnly | Don't allow creating a culture for which the platform does not have data |
1718
| UseSystemResourceKeys | System.Resources.UseSystemResourceKeys | Any localizable resources for system assemblies is trimmed when set to true |
1819
| HttpActivityPropagationSupport | System.Net.Http.EnableActivityPropagation | Any dependency related to diagnostics support for System.Net.Http is trimmed when set to false |

eng/testing/tests.ioslike.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
library test project. Eg. $(InvariantGlobalization) -->
101101
<ItemGroup>
102102
<_ApplePropertyNames Include="InvariantGlobalization" />
103+
<_ApplePropertyNames Include="HybridGlobalization" />
103104
<_ApplePropertyNames Include="AssemblyName" />
104105
<_ApplePropertyNames Include="MonoEnableLLVM" />
105106

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.InteropServices;
5+
6+
internal static partial class Interop
7+
{
8+
internal static partial class Globalization
9+
{
10+
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleNameNative", StringMarshalling = StringMarshalling.Utf8)]
11+
internal static unsafe partial string GetLocaleNameNative(string localeName);
12+
13+
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleInfoStringNative", StringMarshalling = StringMarshalling.Utf8)]
14+
internal static unsafe partial string GetLocaleInfoStringNative(string localeName, uint localeStringData);
15+
}
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-maccatalyst;$(NetCoreAppCurrent)-osx</TargetFrameworks>
4+
<TestRuntime>true</TestRuntime>
5+
<HybridGlobalization>true</HybridGlobalization>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<Compile Include="HybridMode.cs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using Xunit;
6+
7+
namespace System.Globalization.Tests
8+
{
9+
public class HybridModeTests
10+
{
11+
public static IEnumerable<object[]> EnglishName_TestData()
12+
{
13+
yield return new object[] { "en-US", "English (United States)" };
14+
yield return new object[] { "fr-FR", "French (France)" };
15+
}
16+
17+
public static IEnumerable<object[]> NativeName_TestData()
18+
{
19+
yield return new object[] { "en-US", "English (United States)" };
20+
yield return new object[] { "fr-FR", "français (France)" };
21+
yield return new object[] { "en-CA", "English (Canada)" };
22+
}
23+
24+
[Theory]
25+
[MemberData(nameof(EnglishName_TestData))]
26+
public void TestEnglishName(string cultureName, string expected)
27+
{
28+
CultureInfo myTestCulture = new CultureInfo(cultureName);
29+
Assert.Equal(expected, myTestCulture.EnglishName);
30+
}
31+
32+
[Theory]
33+
[MemberData(nameof(NativeName_TestData))]
34+
public void TestNativeName(string cultureName, string expected)
35+
{
36+
CultureInfo myTestCulture = new CultureInfo(cultureName);
37+
Assert.Equal(expected, myTestCulture.NativeName);
38+
}
39+
40+
[Theory]
41+
[InlineData("de-DE", "de")]
42+
[InlineData("en-US", "en")]
43+
public void TwoLetterISOLanguageName(string name, string expected)
44+
{
45+
Assert.Equal(expected, new CultureInfo(name).TwoLetterISOLanguageName);
46+
}
47+
}
48+
}

src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@
346346
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareOptions.cs" />
347347
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.cs" />
348348
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Icu.cs" />
349+
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.OSX.cs" Condition="'$(IsOSXLike)' == 'true'" />
349350
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Nls.cs" />
350351
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.cs" />
351352
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureNotFoundException.cs" />
@@ -1278,6 +1279,9 @@
12781279
<Compile Include="$(CommonPath)Interop\Interop.Locale.cs">
12791280
<Link>Common\Interop\Interop.Locale.cs</Link>
12801281
</Compile>
1282+
<Compile Include="$(CommonPath)Interop\Interop.Locale.OSX.cs" Condition="'$(IsOSXLike)' == 'true'">
1283+
<Link>Common\Interop\Interop.Locale.OSX.cs</Link>
1284+
</Compile>
12811285
<Compile Include="$(CommonPath)Interop\Interop.Normalization.cs">
12821286
<Link>Common\Interop\Interop.Normalization.cs</Link>
12831287
</Compile>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Diagnostics;
5+
6+
namespace System.Globalization
7+
{
8+
internal sealed partial class CultureData
9+
{
10+
/// <summary>
11+
/// This method uses the sRealName field (which is initialized by the constructor before this is called) to
12+
/// initialize the rest of the state of CultureData based on the underlying OS globalization library.
13+
/// </summary>
14+
private bool InitNativeCultureDataCore()
15+
{
16+
Debug.Assert(_sRealName != null);
17+
Debug.Assert(!GlobalizationMode.Invariant);
18+
string realNameBuffer = _sRealName;
19+
20+
_sWindowsName = GetLocaleNameNative(realNameBuffer);
21+
return true;
22+
}
23+
24+
internal static unsafe string GetLocaleNameNative(string localeName)
25+
{
26+
return Interop.Globalization.GetLocaleNameNative(localeName);
27+
}
28+
29+
private string GetLocaleInfoNative(LocaleStringData type)
30+
{
31+
Debug.Assert(!GlobalizationMode.Invariant);
32+
Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfoNative] Expected _sWindowsName to be populated already");
33+
34+
return GetLocaleInfoNative(_sWindowsName, type);
35+
}
36+
37+
// For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
38+
// "windows" name, which can be specific for downlevel (< windows 7) os's.
39+
private static unsafe string GetLocaleInfoNative(string localeName, LocaleStringData type)
40+
{
41+
Debug.Assert(localeName != null, "[CultureData.GetLocaleInfoNative] Expected localeName to be not be null");
42+
43+
return Interop.Globalization.GetLocaleInfoStringNative(localeName, (uint)type);
44+
}
45+
}
46+
}

src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,11 @@ private string GetLocaleInfoCoreUserOverride(LocaleStringData type)
23042304
if (GlobalizationMode.Invariant)
23052305
return null!;
23062306

2307+
#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
2308+
return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type);
2309+
#else
23072310
return ShouldUseUserOverrideNlsData ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type);
2311+
#endif
23082312
}
23092313

23102314
private string GetLocaleInfoCore(LocaleStringData type, string? uiCultureName = null)
@@ -2313,7 +2317,11 @@ private string GetLocaleInfoCore(LocaleStringData type, string? uiCultureName =
23132317
if (GlobalizationMode.Invariant)
23142318
return null!;
23152319

2320+
#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
2321+
return GlobalizationMode.Hybrid ? GetLocaleInfoNative(type) : IcuGetLocaleInfo(type, uiCultureName);
2322+
#else
23162323
return GlobalizationMode.UseNls ? NlsGetLocaleInfo(type) : IcuGetLocaleInfo(type, uiCultureName);
2324+
#endif
23172325
}
23182326

23192327
private string GetLocaleInfoCore(string localeName, LocaleStringData type, string? uiCultureName = null)
@@ -2322,7 +2330,11 @@ private string GetLocaleInfoCore(string localeName, LocaleStringData type, strin
23222330
if (GlobalizationMode.Invariant)
23232331
return null!;
23242332

2333+
#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
2334+
return GlobalizationMode.Hybrid ? GetLocaleInfoNative(localeName, type) : IcuGetLocaleInfo(localeName, type, uiCultureName);
2335+
#else
23252336
return GlobalizationMode.UseNls ? NlsGetLocaleInfo(localeName, type) : IcuGetLocaleInfo(localeName, type, uiCultureName);
2337+
#endif
23262338
}
23272339

23282340
private int[] GetLocaleInfoCoreUserOverride(LocaleGroupingData type)

src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ internal static partial class GlobalizationMode
1313
private static partial class Settings
1414
{
1515
internal static bool Invariant { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");
16+
#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
17+
internal static bool Hybrid { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Hybrid", "DOTNET_SYSTEM_GLOBALIZATION_HYBRID");
18+
#endif
1619
internal static bool PredefinedCulturesOnly { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", GlobalizationMode.Invariant);
1720
}
1821

1922
// Note: Invariant=true and Invariant=false are substituted at different levels in the ILLink.Substitutions file.
2023
// This allows for the whole Settings nested class to be trimmed when Invariant=true, and allows for the Settings
2124
// static cctor (on Unix) to be preserved when Invariant=false.
2225
internal static bool Invariant => Settings.Invariant;
26+
#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
27+
internal static bool Hybrid => Settings.Hybrid;
28+
#endif
2329
internal static bool PredefinedCulturesOnly => Settings.PredefinedCulturesOnly;
2430

2531
private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) =>

src/mono/msbuild/apple/build/AppleBuild.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@
249249
GenerateCMakeProject="$(GenerateCMakeProject)"
250250
GenerateXcodeProject="$(GenerateXcodeProject)"
251251
InvariantGlobalization="$(InvariantGlobalization)"
252+
HybridGlobalization="$(HybridGlobalization)"
252253
MainLibraryFileName="$(MainLibraryFileName)"
253254
MonoRuntimeHeaders="$(_MonoHeaderPath)"
254255
NativeMainSource="$(NativeMainSource)"

0 commit comments

Comments
 (0)