Skip to content

Commit

Permalink
[iOS][non-icu] HybridGlobalization use system ICU (#93220)
Browse files Browse the repository at this point in the history
Use System ICU for Apple mobile platforms and make hybrid mode default
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
Co-authored-by: Alexander Köplinger <alex.koeplinger@outlook.com>
  • Loading branch information
mkhamoyan authored Dec 19, 2023
1 parent d873a06 commit 4ba4110
Show file tree
Hide file tree
Showing 55 changed files with 169 additions and 106 deletions.
4 changes: 3 additions & 1 deletion eng/testing/tests.ioslike.targets
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
Include="@(AppleAssembliesToBundle)" TargetDir="extraFiles\%(AppleAssembliesToBundle.RecursiveDir)" />
</ItemGroup>

<ItemGroup Condition="'$(UseNativeAOTRuntime)' == 'true'">
<ItemGroup Condition="'$(UseNativeAOTRuntime)' == 'true' and '$(HybridGlobalization)' == 'false'" >
<BundleFiles Include="$(MicrosoftNetCoreAppRuntimePackDir)/runtimes/$(TargetOS)-$(TargetArchitecture)/native/icudt.dat"
TargetDir="publish" />
<BundleFiles Include="$(MicrosoftNetCoreAppRuntimePackDir)/runtimes/$(TargetOS)-$(TargetArchitecture)/native/libicudata.a"
Expand Down Expand Up @@ -157,6 +157,8 @@
<WriteLinesToFile File="$(PublishDir)xunit-excludes.txt" Lines="$(XunitExcludesTxtFileContent)" Overwrite="true" />

<PropertyGroup>
<!-- Default for now. If we can remove our ICU and rely on the system one, then HybridGlobalization becomes the default and we can remove checks for it -->
<HybridGlobalization>true</HybridGlobalization>
<IncludesTestRunner Condition="'$(IncludesTestRunner)' == ''">true</IncludesTestRunner>
<Optimized Condition="'$(Configuration)' == 'Release'">true</Optimized>
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == '' and '$(IsRuntimeTests)' != 'true' and '$(IncludesTestRunner)' == 'true'">AppleTestRunner.dll</MainLibraryFileName>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ The .NET Foundation licenses this file to you under the MIT license.
<NetCoreAppNativeLibrary Include="System.Security.Cryptography.Native.Apple" Condition="'$(_IsApplePlatform)' == 'true'" />
<!-- Not compliant for iOS-like platforms -->
<NetCoreAppNativeLibrary Include="System.Security.Cryptography.Native.OpenSsl" Condition="'$(StaticOpenSslLinking)' != 'true' and '$(_IsiOSLikePlatform)' != 'true'" />
<NetCoreAppNativeLibrary Include="icudata" Condition="'$(_IsiOSLikePlatform)' == 'true' and '$(InvariantGlobalization)' != 'true'" />
<NetCoreAppNativeLibrary Include="icui18n" Condition="'$(_IsiOSLikePlatform)' == 'true' and '$(InvariantGlobalization)' != 'true'" />
<NetCoreAppNativeLibrary Include="icuuc" Condition="'$(_IsiOSLikePlatform)' == 'true' and '$(InvariantGlobalization)' != 'true'" />
<NetCoreAppNativeLibrary Include="icudata" Condition="'$(_IsiOSLikePlatform)' == 'true' and '$(InvariantGlobalization)' != 'true' and '$(HybridGlobalization)' != 'true'" />
<NetCoreAppNativeLibrary Include="icui18n" Condition="'$(_IsiOSLikePlatform)' == 'true' and '$(InvariantGlobalization)' != 'true' and '$(HybridGlobalization)' != 'true'" />
<NetCoreAppNativeLibrary Include="icuuc" Condition="'$(_IsiOSLikePlatform)' == 'true' and '$(InvariantGlobalization)' != 'true' and '$(HybridGlobalization)' != 'true'" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ public static string GetDistroVersionString()
public static bool IsIcuGlobalization => ICUVersion > new Version(0, 0, 0, 0);
public static bool IsIcuGlobalizationAndNotHybridOnBrowser => IsIcuGlobalization && IsNotHybridGlobalizationOnBrowser;
public static bool IsIcuGlobalizationAndNotHybrid => IsIcuGlobalization && IsNotHybridGlobalization;
public static bool IsNlsGlobalization => IsNotInvariantGlobalization && !IsIcuGlobalization;
public static bool IsNlsGlobalization => IsNotInvariantGlobalization && !IsIcuGlobalization && !IsHybridGlobalization;

public static bool IsSubstAvailable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public void Ctor_CultureInfo_Compare(object a, object b, int expected)

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37069", TestPlatforms.Android | TestPlatforms.LinuxBionic)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Ctor_CultureInfo_Compare_TurkishI()
{
var cultureNames = Helpers.TestCultureNames;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public void Ctor_CultureInfo_ChangeCurrentCulture_GetHashCodeCompare(object a, o

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37069", TestPlatforms.Android | TestPlatforms.LinuxBionic)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Ctor_CultureInfo_GetHashCodeCompare_TurkishI()
{
var cultureNames = Helpers.TestCultureNames;
Expand Down Expand Up @@ -152,6 +153,7 @@ public void Default_GetHashCodeCompare(object a, object b, bool expected)

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37069", TestPlatforms.Android | TestPlatforms.LinuxBionic)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Default_Compare_TurkishI()
{
// Turkish has lower-case and upper-case version of the dotted "i", so the upper case of "i" (U+0069) isn't "I" (U+0049)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public void AdjustScale()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void ConvertToPrecScale()
{
Assert.Equal(new SqlDecimal(6464.6m).Value, SqlDecimal.ConvertToPrecScale(_test1, 5, 1).Value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public static class SqlStringSortingTest
private static readonly UnicodeEncoding s_unicodeEncoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: true);

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
[InlineData("ja-JP", 0x0411)] // Japanese - Japan
[InlineData("ar-SA", 0x0401)] // Arabic - Saudi Arabia
[InlineData("de-DE", 0x0407)] // German - Germany
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public SqlStringTest()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Constructor_Value_Success()
{
const string value = "foo";
Expand Down Expand Up @@ -219,6 +220,7 @@ public void CompareToSqlTypeException()
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void CompareTo()
{
Assert.True(_test1.CompareTo(_test3) < 0);
Expand Down Expand Up @@ -259,6 +261,7 @@ public void CompareTo()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void EqualsMethods()
{
Assert.False(_test1.Equals(_test2));
Expand All @@ -275,6 +278,7 @@ public void EqualsMethods()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Greaters()
{
// GreateThan ()
Expand All @@ -289,6 +293,7 @@ public void Greaters()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Lessers()
{
// LessThan()
Expand All @@ -304,6 +309,7 @@ public void Lessers()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void NotEquals()
{
Assert.True(SqlString.NotEquals(_test1, _test2).Value);
Expand All @@ -314,6 +320,7 @@ public void NotEquals()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Concat()
{
_test1 = new SqlString("First TestString");
Expand All @@ -325,6 +332,7 @@ public void Concat()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void Clone()
{
SqlString testSqlString = _test1.Clone();
Expand All @@ -344,6 +352,7 @@ public void CompareOptionsFromSqlCompareOptions()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void UnicodeBytes()
{
Assert.Equal((byte)105, _test1.GetNonUnicodeBytes()[1]);
Expand Down Expand Up @@ -540,6 +549,7 @@ public void Conversions()
// OPERATORS

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void ArithmeticOperators()
{
SqlString testString = new SqlString("...Testing...");
Expand All @@ -548,6 +558,7 @@ public void ArithmeticOperators()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void ThanOrEqualOperators()
{
// == -operator
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<linker>
<assembly fullname="System.Private.CoreLib">
<type fullname="System.Globalization.GlobalizationMode">
<method signature="System.Boolean get_Hybrid()" body="stub" value="true" feature="System.Globalization.Hybrid" featurevalue="true" />
</type>
<type fullname="System.Globalization.GlobalizationMode/Settings">
<method signature="System.Boolean get_Hybrid()" body="stub" value="true" feature="System.Globalization.Hybrid" featurevalue="true" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.NoX86Intrinsics.xml" Condition="'$(SupportsX86Intrinsics)' != 'true'" />
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.NoWasmIntrinsics.xml" Condition="'$(SupportsWasmIntrinsics)' != 'true'" />
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.OSX.xml" Condition="'$(IsApplePlatform)' == 'true'" />
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.iOS.xml" Condition="'$(IsiOSLike)' == 'true'" />
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.Windows.xml" Condition="'$(TargetsWindows)' == 'true'" />
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.Browser.xml" Condition="'$(TargetsBrowser)' == 'true'" />
<ILLinkLinkAttributesXmls Include="$(ILLinkSharedDirectory)ILLink.LinkAttributes.Shared.xml" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,7 @@ private int GetSortKeyLengthCore(ReadOnlySpan<char> source, CompareOptions optio
NlsGetSortKeyLength(source, options) :
#if TARGET_BROWSER
GlobalizationMode.Hybrid ?
throw new PlatformNotSupportedException(GetPNSEText("SortKey")) :
throw new PlatformNotSupportedException(GetPNSEText("SortKey")) :
#endif
IcuGetSortKeyLength(source, options);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ private static partial class Settings
/// the GlobalizationMode.Invariant check. Globalization P/Invokes, e.g. in CompareInfo.GetSortKey,
/// rely on ICU already being loaded before they are called.
/// </summary>
#if !TARGET_MACCATALYST && !TARGET_IOS && !TARGET_TVOS
static Settings()
{
// Use GlobalizationMode.Invariant to allow ICU initialization to be trimmed when Invariant=true
Expand All @@ -32,6 +33,7 @@ static Settings()
}
}
}
#endif

private static string GetIcuLoadFailureMessage()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ internal static partial class GlobalizationMode
private static partial class Settings
{
internal static bool Invariant { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
internal static bool Hybrid { get; } = true;
#elif TARGET_BROWSER
internal static bool Hybrid { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Hybrid", "DOTNET_SYSTEM_GLOBALIZATION_HYBRID");
#endif
internal static bool PredefinedCulturesOnly { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", GlobalizationMode.Invariant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public void GetStringComparer_Invalid()
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
[InlineData("hello", "hello", "fr-FR", CompareOptions.IgnoreCase, 0, 0)]
[InlineData("hello", "HELLo", "fr-FR", CompareOptions.IgnoreCase, 0, 0)]
[InlineData("hello", null, "fr-FR", CompareOptions.IgnoreCase, 1, 1)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private static string RemoveComment(string line)
private static Stream GetIdnaTestTxt()
{
string fileName = null;
if (PlatformDetection.ICUVersion >= new Version(66, 0))
if (PlatformDetection.ICUVersion >= new Version(66, 0) || PlatformDetection.IsHybridGlobalizationOnOSX)
fileName = "IdnaTest_13.txt";
else if (PlatformDetection.IsWindows7)
fileName = "IdnaTest_Win7.txt";
Expand Down Expand Up @@ -61,7 +61,7 @@ private static IEnumerable<IConformanceIdnaTest> ParseFile(Stream stream, Func<s

private static IConformanceIdnaTest GetConformanceIdnaTest(string line, int lineCount)
{
if (PlatformDetection.ICUVersion >= new Version(66, 0))
if (PlatformDetection.ICUVersion >= new Version(66, 0) || PlatformDetection.IsHybridGlobalizationOnOSX)
return new Unicode_13_0_IdnaTest(line, lineCount);
else if (PlatformDetection.IsWindows7)
return new Unicode_Win7_IdnaTest(line, lineCount);
Expand All @@ -88,7 +88,7 @@ public static IEnumerable<IConformanceIdnaTest> GetDataset()
{
// Nls is transitional so we filter out non transitional test cases.
// Icu is the opposite.
IdnType idnFilter = PlatformDetection.IsNlsGlobalization ? IdnType.Nontransitional : IdnType.Transitional;
IdnType idnFilter = PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnOSX ? IdnType.Nontransitional : IdnType.Transitional;
foreach (var entry in ParseFile(GetIdnaTestTxt(), GetConformanceIdnaTest))
{
if (entry.Type != idnFilter && entry.Source != string.Empty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static IEnumerable<object[]> GetAscii_TestData()
}

string ascii = c.ToString();
if (!PlatformDetection.IsIcuGlobalization || c != '-') // expected platform differences, see https://github.com/dotnet/runtime/issues/17190
if ((!PlatformDetection.IsIcuGlobalization && !PlatformDetection.IsHybridGlobalizationOnOSX) || c != '-') // expected platform differences, see https://github.com/dotnet/runtime/issues/17190
{
yield return new object[] { ascii, 0, 1, ascii };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void UseStd3AsciiRules_ChangesGetAsciiBehavior(string unicode, bool conta
var idnStd3False = new IdnMapping { UseStd3AsciiRules = false };
var idnStd3True = new IdnMapping { UseStd3AsciiRules = true };

if (containsInvalidHyphen && PlatformDetection.IsIcuGlobalization)
if (containsInvalidHyphen && (PlatformDetection.IsIcuGlobalization || PlatformDetection.IsHybridGlobalizationOnOSX))
{
// ICU always fails on leading/trailing hyphens regardless of the Std3 rules option.
AssertExtensions.Throws<ArgumentException>("unicode", () => idnStd3False.GetAscii(unicode));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void NativeCalendarName_Get_ReturnsExpected(DateTimeFormatInfo dtfi, Cale
{
dtfi.Calendar = calendar;

if (PlatformDetection.IsNotUsingLimitedCultures)
if (PlatformDetection.IsNotUsingLimitedCultures || PlatformDetection.IsHybridGlobalizationOnOSX)
{
// Mobile / Browser ICU doesn't contain NativeCalendarName,
Assert.Equal(nativeCalendarName, dtfi.NativeCalendarName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ public void CultureName_Set(AssemblyName assemblyName, string originalCultureNam
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95195", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void CultureName_Set_Invalid_ThrowsCultureNotFoundException()
{
var assemblyName = new AssemblyName("Test");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class ConvertToDateTimeTests : ConvertTestBase<DateTime>
private static readonly DateTimeFormatInfo s_dateTimeFormatInfo = new DateTimeFormatInfo();

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))]
public void FromString()
{
DateTime[] expectedValues = { new DateTime(1999, 12, 31, 23, 59, 59), new DateTime(100, 1, 1, 0, 0, 0), new DateTime(2216, 2, 29, 0, 0, 0), new DateTime(1, 1, 1, 0, 0, 0) };
Expand Down
Loading

0 comments on commit 4ba4110

Please sign in to comment.