From 9482c1ed378dfde2f540b99cb99685396b3bd4c2 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Tue, 17 Dec 2024 11:47:10 +0100 Subject: [PATCH 1/7] Fix ambiguous call build break in Fuzzing project (#110761) --- src/libraries/Fuzzing/DotnetFuzzing/Assert.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Assert.cs b/src/libraries/Fuzzing/DotnetFuzzing/Assert.cs index be3e7a66defc16..a5f2a9dd1d195b 100644 --- a/src/libraries/Fuzzing/DotnetFuzzing/Assert.cs +++ b/src/libraries/Fuzzing/DotnetFuzzing/Assert.cs @@ -29,9 +29,6 @@ static void ThrowNull() => throw new Exception("Value is null"); } - public static void SequenceEqual(Span expected, Span actual) => - SequenceEqual((ReadOnlySpan)expected, (ReadOnlySpan)actual); - public static void SequenceEqual(ReadOnlySpan expected, ReadOnlySpan actual) { if (!expected.SequenceEqual(actual)) From 917d290077f297f8c3f3066776938a67c62e1d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 17 Dec 2024 12:15:17 +0100 Subject: [PATCH 2/7] Fix native aot outerloop (#110768) This time I broke it. Do not attempt to generate source link data if we're not generating debug information. Debug information is not in a usable state within the compiler. --- .../BuildIntegration/Microsoft.NETCore.Native.Windows.targets | 2 +- .../nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index 23edaa60121447..8639c24343b883 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -88,7 +88,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index 394949166d35f1..3f156ac50fe48c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -237,7 +237,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + From 6e894a87a7cc69ac90817860534c7fe223eae4cb Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 17 Dec 2024 12:58:24 +0100 Subject: [PATCH 3/7] [wasm] Fix rebuild of browser-bench with startup apps (#110776) This fixes 2 issues * clean build of browser-bench with startup apps failed, because WBT's dotnet-latest wasn't available when setting the sdk spath * problem with rebuilding WBT, where WBT fails with ``` runtime/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets(201,5): error MSB4018: The "InstallWorkloadFromArtifacts" task failed unexpectedly. [runtime/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj] [runtime/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj] runtime/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets(201,5): error MSB4018: System.IO.IOException: Directory not empty : 'runtime/artifacts/bin/dotnet-latest/host/fxr/10.0.0-alpha.1.24610.2' [runtime/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj] [runtime/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj] runtime/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets(201,5): error MSB4018: at System.IO.FileSystem.RemoveDirectoryRecursive(String fullPath) [runtime/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj] [runtime/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj] runtime/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets(201,5): error MSB4018: at Microsoft.Workload.Build.Tasks.InstallWorkloadFromArtifacts.Execute() [runtime/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj] [runtime/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj] runtime/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets(201,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Execute() [runtime/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj] [runtime/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj] runtime/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets(201,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(TaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [runtime/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj] [runtime/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj] 0 Warning(s) 1 Error(s) ``` --- .../wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj b/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj index b1cc1e204b827e..7ff54dab058516 100644 --- a/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj +++ b/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj @@ -43,13 +43,15 @@ - - + + + + %(ArtifactsDotnetLatestSdks.RootDir)%(ArtifactsDotnetLatestSdks.Directory)Sdks @@ -68,7 +70,7 @@ $(MSBuildThisFileDirectory)nugetPackages - + <_ScriptExt Condition="'$(OS)' == 'Windows_NT'">.cmd <_ScriptExt Condition="'$(OS)' != 'Windows_NT'">.sh From ce9dd2ad46a4842f5cf0f03c4a30b4d29bd0b4cc Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 17 Dec 2024 04:35:03 -0800 Subject: [PATCH 4/7] Re-enable bundle archive building in source build (#110448) Co-authored-by: Viktor Hofer --- eng/Subsets.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Subsets.props b/eng/Subsets.props index a50fd3e80025eb..1491a0aeba8a38 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -550,7 +550,7 @@ - + From 8a25506957ae24effa9f57c7e4d5571f9e6bc9be Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:50:32 +0100 Subject: [PATCH 5/7] [browser] Remove WASM `HybridGlobalization` from runtime code (#110567) * Removal of `HybridGlobalization` code from the runtime and libs. * Remove `HybridGlobalization` flag and clean the tests from it. * Fix build. * Fix build, remove unused leftovers. * Fix linker tests. * Fix the CI error, revert "icudt_hybrid.dat" removal. * Fix WBT that expected `icudt_hybrid.dat` to be missing. --- eng/liveBuilds.targets | 4 +- .../Directory.Build.props | 2 - .../src/Interop/Browser/Interop.Calendar.cs | 14 - .../Interop/Browser/Interop.CompareInfo.cs | 22 -- .../src/Interop/Browser/Interop.Locale.cs | 6 - .../src/Interop/Browser/Interop.TextInfo.cs | 13 - .../ILLink/ILLink.Substitutions.Browser.xml | 10 - .../System.Private.CoreLib.Shared.projitems | 13 - .../Globalization/CalendarData.Browser.cs | 57 --- .../System/Globalization/CalendarData.Unix.cs | 6 +- .../src/System/Globalization/CalendarData.cs | 7 - .../System/Globalization/CompareInfo.Icu.cs | 70 +--- .../Globalization/CompareInfo.WebAssembly.cs | 196 ---------- .../src/System/Globalization/CompareInfo.cs | 27 +- .../Globalization/CultureData.Browser.cs | 61 --- .../src/System/Globalization/CultureData.cs | 24 +- .../src/System/Globalization/DateTimeParse.cs | 16 - .../System/Globalization/GlobalizationMode.cs | 4 +- .../src/System/Globalization/TextInfo.Icu.cs | 3 - .../src/System/Globalization/TextInfo.Nls.cs | 3 - .../Globalization/TextInfo.WebAssembly.cs | 40 -- .../src/System/Globalization/TextInfo.cs | 37 +- src/mono/browser/browser.proj | 6 +- src/mono/browser/build/BrowserWasmApp.targets | 26 +- src/mono/browser/runtime/assets.ts | 14 +- src/mono/browser/runtime/corebindings.c | 22 +- src/mono/browser/runtime/dotnet.d.ts | 14 +- .../browser/runtime/es6/dotnet.es6.lib.js | 3 +- src/mono/browser/runtime/exports-binding.ts | 6 +- src/mono/browser/runtime/exports-linker.ts | 8 +- src/mono/browser/runtime/exports.ts | 16 +- ...ales-common.ts => globalization-locale.ts} | 20 +- .../browser/runtime/globalization-stubs.ts | 69 ---- src/mono/browser/runtime/globalization.ts | 17 +- src/mono/browser/runtime/globals.ts | 4 +- .../runtime/hybrid-globalization/calendar.ts | 364 ------------------ .../hybrid-globalization/change-case.ts | 67 ---- .../hybrid-globalization/collations.ts | 268 ------------- .../hybrid-globalization/culture-info.ts | 139 ------- .../grapheme-segmenter.ts | 142 ------- .../runtime/hybrid-globalization/helpers.ts | 35 -- .../runtime/hybrid-globalization/locales.ts | 89 ----- .../hybrid-globalization/module-exports.ts | 26 -- .../segmentation-rules.json | 83 ---- src/mono/browser/runtime/loader/assets.ts | 22 +- src/mono/browser/runtime/loader/config.ts | 7 - src/mono/browser/runtime/loader/globals.ts | 5 +- src/mono/browser/runtime/loader/icu.ts | 7 +- src/mono/browser/runtime/loader/run.ts | 25 +- src/mono/browser/runtime/rollup.config.js | 15 - src/mono/browser/runtime/types/index.ts | 14 +- src/mono/browser/runtime/types/internal.ts | 19 - ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 16 +- .../WasmFeatures.props | 1 - .../WorkloadTelemetry.targets | 1 - src/mono/sample/wasm/Directory.Build.targets | 2 - .../Common/GlobalizationMode.cs | 1 - .../Wasm.Build.Tests/ProjectProviderBase.cs | 8 - .../WasmSdkBasedProjectProvider.cs | 17 +- src/mono/wasm/build/WasmApp.Common.targets | 1 - .../EntryPoints/HybridGlobalization.cs | 27 -- .../AssetsComputingHelper.cs | 6 - .../BootJsonBuilderHelper.cs | 2 - .../BootJsonData.cs | 5 - .../ComputeWasmBuildAssets.cs | 6 +- .../ComputeWasmPublishAssets.cs | 5 +- .../GenerateWasmBootJson.cs | 4 - src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 7 - .../WasmAppBuilder/WasmAppBuilderBaseTask.cs | 1 - 69 files changed, 79 insertions(+), 2218 deletions(-) delete mode 100644 src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs delete mode 100644 src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs delete mode 100644 src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs rename src/mono/browser/runtime/{locales-common.ts => globalization-locale.ts} (83%) delete mode 100644 src/mono/browser/runtime/globalization-stubs.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/calendar.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/change-case.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/collations.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/culture-info.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/helpers.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/locales.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/module-exports.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json delete mode 100644 src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index b7c63f1e36b09f..01edbff0551fa2 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -207,15 +207,13 @@ $(LibrariesNativeArtifactsPath)dotnet.js; $(LibrariesNativeArtifactsPath)dotnet.js.map; $(LibrariesNativeArtifactsPath)dotnet.native.js; - $(LibrariesNativeArtifactsPath)dotnet.globalization.js; $(LibrariesNativeArtifactsPath)dotnet.runtime.js; $(LibrariesNativeArtifactsPath)dotnet.runtime.js.map; $(LibrariesNativeArtifactsPath)dotnet.d.ts; $(LibrariesNativeArtifactsPath)package.json; $(LibrariesNativeArtifactsPath)dotnet.native.wasm; $(LibrariesNativeArtifactsPath)dotnet.native.js.symbols; - $(LibrariesNativeArtifactsPath)*.dat; - $(LibrariesNativeArtifactsPath)segmentation-rules.json;" + $(LibrariesNativeArtifactsPath)*.dat;" IsNative="true" /> - @@ -236,7 +235,6 @@ - diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs b/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs deleted file mode 100644 index 73fbfa924d141d..00000000000000 --- a/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; -using System.Runtime.CompilerServices; - -internal static partial class Interop -{ - internal static unsafe partial class JsGlobalization - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetCalendarInfo(char* culture, int cultureLength, CalendarId calendarId, char* buffer, int bufferMaxLength, out int bufferLength); - } -} diff --git a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs deleted file mode 100644 index 638934edb416d6..00000000000000 --- a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -internal static partial class Interop -{ - internal static unsafe partial class JsGlobalization - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint CompareString(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int resultPtr); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint StartsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint EndsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint IndexOf(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, bool fromBeginning, out int resultPtr); - } -} diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs b/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs index b2dc0db99c00c0..0a2e8449704be8 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs @@ -7,12 +7,6 @@ internal static partial class Interop { internal static unsafe partial class JsGlobalization { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetCultureInfo(char* culture, int cultureLength, char* buffer, int bufferMaxLength, out int resultLength); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetFirstDayOfWeek(char* culture, int cultureLength, out int resultPtr); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetFirstWeekOfYear(char* culture, int cultureLength, out int resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern unsafe nint GetLocaleInfo(char* locale, int localeLength, char* culture, int cultureLength, char* buffer, int bufferLength, out int resultLength); } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs deleted file mode 100644 index c9a0b3ac39fb48..00000000000000 --- a/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -internal static partial class Interop -{ - internal static unsafe partial class JsGlobalization - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint ChangeCase(char* culture, int cultureLen, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); - } -} diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml deleted file mode 100644 index c2e50a979ec7e1..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 51e003bae50afc..2fdf95932689b8 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -61,7 +61,6 @@ - @@ -337,7 +336,6 @@ - @@ -351,7 +349,6 @@ - @@ -413,7 +410,6 @@ - @@ -1341,18 +1337,9 @@ - - Common\Interop\Interop.CompareInfo.cs - - - Common\Interop\Interop.Calendar.cs - Common\Interop\Browser\Interop.Locale.cs - - Common\Interop\Interop.TextInfo.cs - Common\Interop\Interop.Calendar.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs deleted file mode 100644 index 582492c6c40f84..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Globalization -{ - internal sealed partial class CalendarData - { - private const int CALENDAR_INFO_BUFFER_LEN = 1000; - private unsafe bool JSLoadCalendarDataFromBrowser(string localeName, CalendarId calendarId) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - char* buffer = stackalloc char[CALENDAR_INFO_BUFFER_LEN]; - nint exceptionPtr = Interop.JsGlobalization.GetCalendarInfo(pLocaleName, localeNameSpan.Length, calendarId, buffer, CALENDAR_INFO_BUFFER_LEN, out int resultLength); - Helper.MarshalAndThrowIfException(exceptionPtr); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length < 14) - throw new Exception("CalendarInfo recieved from the Browser is in icorrect format."); - // JS always has one result per locale, so even arrays are initialized with one element - this.sNativeName = string.IsNullOrEmpty(subresults[0]) ? ((CalendarId)calendarId).ToString() : subresults[0]; // this is EnglishName, not NativeName but it's the best we can do - this.saYearMonths = new string[] { subresults[1] }; - this.sMonthDay = subresults[2]; - this.saLongDates = new string[] { subresults[3] }; - this.saShortDates = new string[] { subresults[4] }; - this.saEraNames = new string[] { subresults[5] }; - this.saAbbrevEraNames = new string[] { subresults[6] }; - this.saDayNames = subresults[7].Split("||"); - this.saAbbrevDayNames = subresults[8].Split("||"); - this.saSuperShortDayNames = subresults[9].Split("||"); - this.saMonthNames = ResizeMonthsArray(subresults[10].Split("||")); - this.saAbbrevMonthNames = ResizeMonthsArray(subresults[11].Split("||")); - this.saMonthGenitiveNames = ResizeMonthsArray(subresults[12].Split("||")); - this.saAbbrevMonthGenitiveNames = ResizeMonthsArray(subresults[13].Split("||")); - return true; - } - - static string[] ResizeMonthsArray(string[] months) - { - if (months.Length == 13) - return months; - // most calendars have 12 months and then we expect the 13th month to be empty - string[] resized = new string[13]; - resized[12] = ""; - months.CopyTo(resized, 0); - return resized; - } - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs index 295a58e9882e17..59785ded51a1e3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs @@ -9,11 +9,7 @@ internal sealed partial class CalendarData { private bool LoadCalendarDataFromSystemCore(string localeName, CalendarId calendarId) { -#if TARGET_BROWSER - return GlobalizationMode.Hybrid ? - JSLoadCalendarDataFromBrowser(localeName, calendarId) : - IcuLoadCalendarDataFromSystem(localeName, calendarId); -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? LoadCalendarDataFromNative(localeName, calendarId) : IcuLoadCalendarDataFromSystem(localeName, calendarId); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs index 11b5b69f129222..b4e796126ac293 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs @@ -250,13 +250,6 @@ private void InitializeEraNames(string localeName, CalendarId calendarId) break; default: -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid && !AreEraNamesEmpty()) - { - // we don't want to have this overwritten because JS already loaded it - break; - } -#endif // Most calendars are just "A.D." this.saEraNames = Invariant.saEraNames; break; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs index 9b454700f6b3d9..35ad3096dbbc92 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs @@ -24,7 +24,7 @@ private void IcuInitSortHandle(string interopCultureName) _isAsciiEqualityOrdinal = GetIsAsciiEqualityOrdinal(interopCultureName); if (!GlobalizationMode.Invariant) { -#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return; #endif @@ -205,18 +205,7 @@ private unsafe int IndexOfOrdinalIgnoreCaseHelper(ReadOnlySpan source, Rea return -1; InteropCall: -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(b, target.Length, a, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -310,18 +299,7 @@ private unsafe int IndexOfOrdinalHelper(ReadOnlySpan source, ReadOnlySpan< return -1; InteropCall: -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(b, target.Length, a, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -708,16 +686,6 @@ private unsafe SortKey IcuCreateSortKey(string source, CompareOptions options) Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!GlobalizationMode.UseNls); -#if TARGET_BROWSER - // JS cannot create locale-sensitive sort key, use invaraint functions instead. - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture) - throw new PlatformNotSupportedException(GetPNSEWithReason("CreateSortKey", "non-invariant culture")); - return InvariantCreateSortKey(source, options); - } -#endif - if ((options & ValidCompareMaskOffFlags) != 0) { throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); @@ -776,14 +744,7 @@ private unsafe int IcuGetSortKey(ReadOnlySpan source, Span destinati Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert((options & ValidCompareMaskOffFlags) == 0); -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture) - throw new PlatformNotSupportedException(GetPNSEWithReason("GetSortKey", "non-invariant culture")); - return InvariantGetSortKey(source, destination, options); - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { AssertComparisonSupported(options); @@ -832,14 +793,7 @@ private unsafe int IcuGetSortKeyLength(ReadOnlySpan source, CompareOptions Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert((options & ValidCompareMaskOffFlags) == 0); -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture) - throw new PlatformNotSupportedException(GetPNSEWithReason("GetSortKeyLength", "non-invariant culture")); - return InvariantGetSortKeyLength(source, options); - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { AssertComparisonSupported(options); @@ -894,19 +848,7 @@ private unsafe int IcuGetHashCodeOfString(ReadOnlySpan source, CompareOpti Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture && !LocalizedHashCodeSupportsCompareOptions(options)) - { - throw new PlatformNotSupportedException(GetPNSEWithReason("GetHashCode", "non-invariant culture with CompareOptions different than None or IgnoreCase")); - } - - // JS cannot create locale-sensitive HashCode, use invaraint functions instead - ReadOnlySpan sanitizedSource = SanitizeForInvariantHash(source, options); - return InvariantGetHashCode(sanitizedSource, options); - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { AssertComparisonSupported(options); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs deleted file mode 100644 index 26e1116597401e..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs +++ /dev/null @@ -1,196 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Globalization -{ - public partial class CompareInfo - { - // invariant culture has empty CultureInfo.ToString() and - // m_name == CultureInfo._name == CultureInfo.ToString() - private bool _isInvariantCulture => string.IsNullOrEmpty(m_name); - - private TextInfo? _thisTextInfo; - - private TextInfo thisTextInfo => _thisTextInfo ??= new CultureInfo(m_name).TextInfo; - - private static bool LocalizedHashCodeSupportsCompareOptions(CompareOptions options) => - options == CompareOptions.IgnoreCase || options == CompareOptions.None; - private static void AssertHybridOnWasm(CompareOptions options) - { - Debug.Assert(!GlobalizationMode.Invariant); - Debug.Assert(!GlobalizationMode.UseNls); - Debug.Assert(GlobalizationMode.Hybrid); - Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); - } - - private static void AssertComparisonSupported(CompareOptions options, string cultureName) - { - if (CompareOptionsNotSupported(options)) - throw new PlatformNotSupportedException(GetPNSE(options)); - - if (CompareOptionsNotSupportedForCulture(options, cultureName)) - throw new PlatformNotSupportedException(GetPNSEForCulture(options, cultureName)); - } - - private static void AssertIndexingSupported(CompareOptions options, string cultureName) - { - if (IndexingOptionsNotSupported(options) || CompareOptionsNotSupported(options)) - throw new PlatformNotSupportedException(GetPNSE(options)); - - if (CompareOptionsNotSupportedForCulture(options, cultureName)) - throw new PlatformNotSupportedException(GetPNSEForCulture(options, cultureName)); - } - - private unsafe int JsCompareString(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) - { - AssertHybridOnWasm(options); - AssertComparisonSupported(options, m_name); - - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pString1 = &MemoryMarshal.GetReference(string1)) - fixed (char* pString2 = &MemoryMarshal.GetReference(string2)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.CompareString(pCultureName, cultureNameSpan.Length, pString1, string1.Length, pString2, string2.Length, options, out int cmpResult); - Helper.MarshalAndThrowIfException(exceptionPtr); - return cmpResult; - } - } - - private unsafe bool JsStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) - { - AssertHybridOnWasm(options); - Debug.Assert(!prefix.IsEmpty); - AssertIndexingSupported(options, m_name); - - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.StartsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } - - private unsafe bool JsEndsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) - { - AssertHybridOnWasm(options); - Debug.Assert(!prefix.IsEmpty); - AssertIndexingSupported(options, m_name); - - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.EndsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } - - private unsafe int JsIndexOfCore(ReadOnlySpan source, ReadOnlySpan target, CompareOptions options, int* matchLengthPtr, bool fromBeginning) - { - AssertHybridOnWasm(options); - Debug.Assert(!target.IsEmpty); - AssertIndexingSupported(options, m_name); - - if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options)) - { - return (options & CompareOptions.IgnoreCase) != 0 ? - IndexOfOrdinalIgnoreCaseHelper(source, target, options, matchLengthPtr, fromBeginning) : - IndexOfOrdinalHelper(source, target, options, matchLengthPtr, fromBeginning); - } - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pTarget = &MemoryMarshal.GetReference(target)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, pTarget, target.Length, pSource, source.Length, options, fromBeginning, out int idx); - Helper.MarshalAndThrowIfException(exceptionPtr); - return idx; - } - } - - // there are chars that are considered equal by HybridGlobalization but do not have equal hashes when binary hashed - // Control: 1105 (out of 1105) - // Format: 697 (out of 731) - // OtherPunctuation: 6919 (out of 7004) - // SpaceSeparator: 289 (out of 289) - // OpenPunctuation: 1275 (out of 1343) - // ClosePunctuation: 1241 (out of 1309) - // DashPunctuation: 408 (out of 425) - // ConnectorPunctuation: 170 (out of 170) - // InitialQuotePunctuation: 204 (out of 204) - // FinalQuotePunctuation: 170 (out of 170) - // LineSeparator: 17 (out of 17) - // ParagraphSeparator: 17 (out of 17) - // OtherLetter: 34 (out of 784142) - // SpacingCombiningMark: 68 (out of 4420) - // ModifierLetter: 51 (out of 4012) - // EnclosingMark: 85 (out of 221) - // NonSpacingMark: 3281 (out of 18105) - // we can skip them all (~1027k chars) by checking for the remaining UnicodeCategories (~291k chars) - // skipping more characters than ICU would lead to hashes with smaller distribution and more collisions in hash tables - // but it makes the behavior correct and consistent with locale-aware equals, which is acceptable tradeoff - private static bool ShouldNotBeSkipped(UnicodeCategory category) => - category == UnicodeCategory.LowercaseLetter || - category == UnicodeCategory.UppercaseLetter || - category == UnicodeCategory.TitlecaseLetter || - category == UnicodeCategory.LetterNumber || - category == UnicodeCategory.OtherNumber || - category == UnicodeCategory.Surrogate || - category == UnicodeCategory.PrivateUse || - category == UnicodeCategory.MathSymbol || - category == UnicodeCategory.CurrencySymbol || - category == UnicodeCategory.ModifierSymbol || - category == UnicodeCategory.OtherSymbol || - category == UnicodeCategory.OtherNotAssigned; - - private ReadOnlySpan SanitizeForInvariantHash(ReadOnlySpan source, CompareOptions options) - { - char[] result = new char[source.Length]; - int resultIndex = 0; - foreach (char c in source) - { - UnicodeCategory category = CharUnicodeInfo.GetUnicodeCategory(c); - if (ShouldNotBeSkipped(category)) - { - result[resultIndex++] = c; - } - } - if ((options & CompareOptions.IgnoreCase) != 0) - { - string resultStr = new string(result, 0, resultIndex); - // JS-based ToUpper, to keep cases like Turkish I working - resultStr = thisTextInfo.ToUpper(resultStr); - return resultStr.AsSpan(); - } - return result.AsSpan(0, resultIndex); - } - - private static bool IndexingOptionsNotSupported(CompareOptions options) => - (options & (CompareOptions.IgnoreSymbols | CompareOptions.NumericOrdering)) != 0; - - private static bool CompareOptionsNotSupported(CompareOptions options) => - (options & CompareOptions.IgnoreWidth) == CompareOptions.IgnoreWidth || - ((options & CompareOptions.IgnoreNonSpace) == CompareOptions.IgnoreNonSpace && (options & CompareOptions.IgnoreKanaType) == 0); - - private static string GetPNSE(CompareOptions options) => - SR.Format(SR.PlatformNotSupported_HybridGlobalizationWithCompareOptions, options); - - private static bool CompareOptionsNotSupportedForCulture(CompareOptions options, string cultureName) => - ((options & ~CompareOptions.NumericOrdering) == CompareOptions.IgnoreKanaType && - (string.IsNullOrEmpty(cultureName) || cultureName.Split('-')[0] != "ja")) || - ((options & ~CompareOptions.NumericOrdering) == CompareOptions.None && - (cultureName.Split('-')[0] == "ja")); - - private static string GetPNSEForCulture(CompareOptions options, string cultureName) => - SR.Format(SR.PlatformNotSupported_HybridGlobalizationWithCompareOptions, options, cultureName); - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs index dd0b021d3bb05f..9c1e6ddee1d2b1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs @@ -488,10 +488,7 @@ private static void ThrowCompareOptionsCheckFailed(CompareOptions options) private unsafe int CompareStringCore(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) => GlobalizationMode.UseNls ? NlsCompareString(string1, string2, options) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsCompareString(string1, string2, options) : -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? CompareStringNative(string1, string2, options) : #endif @@ -616,7 +613,7 @@ public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix else { // Linguistic comparison requested and we don't need to special-case any args. -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -633,10 +630,6 @@ public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix private unsafe bool StartsWithCore(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? NlsStartsWith(source, prefix, options, matchLengthPtr) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsStartsWith(source, prefix, options) : -#endif IcuStartsWith(source, prefix, options, matchLengthPtr); public bool IsPrefix(string source, string prefix) @@ -763,7 +756,7 @@ public unsafe bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix else { // Linguistic comparison requested and we don't need to special-case any args. -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -785,10 +778,6 @@ public bool IsSuffix(string source, string suffix) private unsafe bool EndsWithCore(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? NlsEndsWith(source, suffix, options, matchLengthPtr) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsEndsWith(source, suffix, options) : -#endif IcuEndsWith(source, suffix, options, matchLengthPtr); /// @@ -1058,7 +1047,7 @@ private unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, { Debug.Assert(matchLengthPtr != null); *matchLengthPtr = 0; -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -1128,10 +1117,6 @@ private unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, private unsafe int IndexOfCore(ReadOnlySpan source, ReadOnlySpan target, CompareOptions options, int* matchLengthPtr, bool fromBeginning) => GlobalizationMode.UseNls ? NlsIndexOfCore(source, target, options, matchLengthPtr, fromBeginning) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsIndexOfCore(source, target, options, matchLengthPtr, fromBeginning) : -#endif IcuIndexOfCore(source, target, options, matchLengthPtr, fromBeginning); /// @@ -1617,7 +1602,7 @@ public SortVersion Version } else { -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(GetPNSEText("SortVersion")); @@ -1633,7 +1618,7 @@ public SortVersion Version public int LCID => CultureInfo.GetCultureInfo(Name).LCID; -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS private static string GetPNSEText(string funcName) => SR.Format(SR.PlatformNotSupported_HybridGlobalization, funcName); private static string GetPNSEWithReason(string funcName, string reason) => SR.Format(SR.PlatformNotSupportedWithReason_HybridGlobalization, funcName, reason); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs index 897b14e44b3fa6..7cf51d7d8f12f9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs @@ -10,7 +10,6 @@ namespace System.Globalization { internal sealed partial class CultureData { - private const int CULTURE_INFO_BUFFER_LEN = 60; private const int LOCALE_INFO_BUFFER_LEN = 80; private void JSInitLocaleInfo() @@ -67,66 +66,6 @@ private string JSGetNativeDisplayName(string localeName, string cultureName) languageName : $"{languageName} ({countryName})"; } - - private static unsafe CultureData JSLoadCultureInfoFromBrowser(string localeName, CultureData culture) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - char* buffer = stackalloc char[CULTURE_INFO_BUFFER_LEN]; - nint exceptionPtr = Interop.JsGlobalization.GetCultureInfo(pLocaleName, localeNameSpan.Length, buffer, CULTURE_INFO_BUFFER_LEN, out int resultLength); - Helper.MarshalAndThrowIfException(exceptionPtr); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length < 4) - throw new Exception("CultureInfo recieved from the Browser is in incorrect format."); - culture._sAM1159 = subresults[0]; - culture._sPM2359 = subresults[1]; - culture._saLongTimes = new string[] { subresults[2] }; - culture._saShortTimes = new string[] { subresults[3] }; - } - return culture; - } - - private static unsafe int GetFirstDayOfWeek(string localeName) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.GetFirstDayOfWeek(pLocaleName, localeNameSpan.Length, out int result); - if (exceptionPtr != IntPtr.Zero) - { - int success = Helper.MarshalAndThrowIfException( - exceptionPtr, - failOnlyDebug: true, - failureMessage: $"[CultureData.GetFirstDayOfWeek()] failed with"); - // Failed, just use 0 - if (success == -1) - return 0; - } - return result; - } - } - - private static unsafe int GetFirstWeekOfYear(string localeName) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.GetFirstWeekOfYear(pLocaleName, localeNameSpan.Length, out int result); - if (exceptionPtr != IntPtr.Zero) - { - int success = Helper.MarshalAndThrowIfException( - exceptionPtr, - failOnlyDebug: true, - failureMessage: $"[CultureData.GetFirstWeekOfYear()] failed with"); - // Failed, just use 0 - if (success == -1) - return 0; - } - return result; - } - } } internal static class Helper diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index d6297b5f2e2cec..ecb46a90e1dbbf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -815,11 +815,6 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) return null; } #if TARGET_BROWSER - // populate fields for which ICU does not provide data in Hybrid mode - if (GlobalizationMode.Hybrid && !string.IsNullOrEmpty(culture._sName)) - { - culture = JSLoadCultureInfoFromBrowser(culture._sName, culture); - } culture.JSInitLocaleInfo(); #endif @@ -1543,13 +1538,6 @@ internal int FirstDayOfWeek _iFirstDayOfWeek = GetLocaleInfoNative(LocaleNumberData.FirstDayOfWeek); } else -#elif TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - Debug.Assert(_sName != null, "[FirstDayOfWeek] Expected _sName to be populated already"); - _iFirstDayOfWeek = GetFirstDayOfWeek(_sName); - } - else #endif { _iFirstDayOfWeek = ShouldUseUserOverrideNlsData ? NlsGetFirstDayOfWeek() : IcuGetLocaleInfo(LocaleNumberData.FirstDayOfWeek); @@ -1569,17 +1557,7 @@ internal int CalendarWeekRule { if (_iFirstWeekOfYear == undef) { -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - Debug.Assert(_sName != null, "[CalendarWeekRule] Expected _sName to be populated already"); - _iFirstWeekOfYear = GetFirstWeekOfYear(_sName); - } - else -#endif - { - _iFirstWeekOfYear = GetLocaleInfoCoreUserOverride(LocaleNumberData.FirstWeekOfYear); - } + _iFirstWeekOfYear = GetLocaleInfoCoreUserOverride(LocaleNumberData.FirstWeekOfYear); } return _iFirstWeekOfYear; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index bec15897701aa1..4586b81991871e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -1906,15 +1906,6 @@ private static bool GetDayOfNNY(ref DateTimeResult result, scoped ref DateTimeRa result.flags |= ParseFlags.HaveDate; return true; // MD + Year } -#if TARGET_BROWSER - // if we are parsing the datetime string with custom format then the CultureInfo format `order` - // does not matter and DM + Year is also possible for NNY - if (GlobalizationMode.Hybrid && SetDateYDM(ref result, raw.year, n1, n2)) - { - result.flags |= ParseFlags.HaveDate; - return true; // DM + Year - } -#endif } else { @@ -1923,13 +1914,6 @@ private static bool GetDayOfNNY(ref DateTimeResult result, scoped ref DateTimeRa result.flags |= ParseFlags.HaveDate; return true; // DM + Year } -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid && SetDateYMD(ref result, raw.year, n1, n2)) - { - result.flags |= ParseFlags.HaveDate; - return true; // MD + Year - } -#endif } result.SetBadDateTimeFailure(); return false; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 78cebb45b9a006..44a8ed2934686e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -15,8 +15,6 @@ 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 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); } @@ -40,7 +38,7 @@ internal static bool InvariantNoLoad } } -#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS internal static bool Hybrid => Settings.Hybrid; #endif internal static bool PredefinedCulturesOnly => Settings.PredefinedCulturesOnly; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs index b2e113cb9c58bb..fc7fae4374b8f3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs @@ -19,9 +19,6 @@ private static bool NeedsTurkishCasing(string localeName) internal unsafe void IcuChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper) { Debug.Assert(!GlobalizationMode.Invariant); -#if TARGET_BROWSER - Debug.Assert(!GlobalizationMode.Hybrid); -#endif Debug.Assert(!GlobalizationMode.UseNls); if (HasEmptyCultureName) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs index 57c47cf9a9812a..ca6689f4cef534 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs @@ -10,9 +10,6 @@ public partial class TextInfo private unsafe void NlsChangeCase(char* pSource, int pSourceLen, char* pResult, int pResultLen, bool toUpper) { Debug.Assert(!GlobalizationMode.Invariant); -#if TARGET_BROWSER - Debug.Assert(!GlobalizationMode.Hybrid); -#endif Debug.Assert(GlobalizationMode.UseNls); Debug.Assert(pSource != null); Debug.Assert(pResult != null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs deleted file mode 100644 index 459478f7055040..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Globalization -{ - public partial class TextInfo - { - internal unsafe void JsChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool toUpper) - { - Debug.Assert(!GlobalizationMode.Invariant); - Debug.Assert(!GlobalizationMode.UseNls); - Debug.Assert(GlobalizationMode.Hybrid); - - if (HasEmptyCultureName) - { - ReadOnlySpan source = new ReadOnlySpan(src, srcLen); - Span destination = new Span(dstBuffer, dstBufferCapacity); - if (toUpper) - { - InvariantModeCasing.ToUpper(source, destination); - } - else - { - InvariantModeCasing.ToLower(source, destination); - } - return; - } - - ReadOnlySpan cultureName = _cultureName.AsSpan(); - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureName)) - { - nint exceptionPtr = Interop.JsGlobalization.ChangeCase(pCultureName, cultureName.Length, src, srcLen, dstBuffer, dstBufferCapacity, toUpper); - Helper.MarshalAndThrowIfException(exceptionPtr); - } - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs index 45123f85d43414..5b6f26637dcacd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs @@ -140,12 +140,7 @@ public string ListSeparator /// public char ToLower(char c) { -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToLower(c); } @@ -178,12 +173,7 @@ public string ToLower(string str) { ArgumentNullException.ThrowIfNull(str); -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToLower(str); } @@ -194,9 +184,6 @@ public string ToLower(string str) private unsafe char ChangeCase(char c, bool toUpper) { Debug.Assert(!GlobalizationMode.Invariant); -#if TARGET_BROWSER - Debug.Assert(!(GlobalizationMode.Hybrid && HasEmptyCultureName)); -#endif char dst = default; ChangeCaseCore(&c, 1, &dst, 1, toUpper); return dst; @@ -239,9 +226,6 @@ private unsafe void ChangeCaseCommon(ReadOnlySpan source, Spa { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(typeof(TConversion) == typeof(ToUpperConversion) || typeof(TConversion) == typeof(ToLowerConversion)); -#if TARGET_BROWSER - Debug.Assert(!(GlobalizationMode.Hybrid && HasEmptyCultureName)); -#endif if (source.IsEmpty) { @@ -278,9 +262,6 @@ private unsafe string ChangeCaseCommon(string source) where TConver Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(source != null); -#if TARGET_BROWSER - Debug.Assert(!(GlobalizationMode.Hybrid && HasEmptyCultureName)); -#endif // If the string is empty, we're done. if (source.Length == 0) @@ -430,12 +411,7 @@ private static char ToLowerAsciiInvariant(char c) /// public char ToUpper(char c) { -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToUpper(c); } @@ -468,12 +444,7 @@ public string ToUpper(string str) { ArgumentNullException.ThrowIfNull(str); -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToUpper(str); } @@ -732,13 +703,7 @@ private unsafe void ChangeCaseCore(char* src, int srcLen, char* dstBuffer, int d NlsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); return; } -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - JsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); - return; - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { ChangeCaseNative(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj index 88a0afb3bf91e1..d09d7f7021484c 100644 --- a/src/mono/browser/browser.proj +++ b/src/mono/browser/browser.proj @@ -378,8 +378,7 @@ + $(ICULibDir)/libicudata.a" /> @@ -502,8 +501,7 @@ $(NativeBinDir)dotnet.native.js; $(NativeBinDir)dotnet.d.ts; $(NativeBinDir)package.json; - $(NativeBinDir)dotnet.native.wasm; - $(NativeBinDir)dotnet.globalization.js" + $(NativeBinDir)dotnet.native.wasm;" DestinationFolder="$(MicrosoftNetCoreAppRuntimePackNativeDir)" SkipUnchangedFiles="true" /> diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets index 728c600a740220..2e611016df020a 100644 --- a/src/mono/browser/build/BrowserWasmApp.targets +++ b/src/mono/browser/build/BrowserWasmApp.targets @@ -73,8 +73,6 @@ - - @@ -82,10 +80,8 @@ <_HasDotnetJsWorker Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.worker.mjs'">true <_HasDotnetJsSymbols Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.js.symbols'">true <_HasDotnetNativeJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.js'">true - <_HasDotnetGlobalizationJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.globalization.js'">true - false - <_WasmIcuDataFileName Condition="'$(HybridGlobalization)' != 'true' and '$(WasmIcuDataFileName)' != '' and Exists('$(WasmIcuDataFileName)')">$(WasmIcuDataFileName) - <_WasmIcuDataFileName Condition="'$(HybridGlobalization)' != 'true' and '$(WasmIcuDataFileName)' != '' and !Exists('$(WasmIcuDataFileName)')">$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(WasmIcuDataFileName) + <_WasmIcuDataFileName Condition="'$(WasmIcuDataFileName)' != '' and Exists('$(WasmIcuDataFileName)')">$(WasmIcuDataFileName) + <_WasmIcuDataFileName Condition="'$(WasmIcuDataFileName)' != '' and !Exists('$(WasmIcuDataFileName)')">$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(WasmIcuDataFileName) @@ -95,10 +91,6 @@ - - <_HybridGlobalizationDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt_hybrid.dat"/> - <_HybridGlobalizationDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)segmentation-rules.json"/> - <_IcuAvailableDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt_*" Exclude="@(_HybridGlobalizationDataFiles);$(_WasmIcuDataFileName)"/> - - - - + <_IcuAvailableDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt_*" Exclude="$(_WasmIcuDataFileName)"/> + + + @@ -150,7 +139,6 @@ RuntimeArgsForHost="@(WasmMonoRuntimeArgs)" DefaultHostConfig="$(DefaultWasmHostConfig)" InvariantGlobalization="$(InvariantGlobalization)" - HybridGlobalization="$(HybridGlobalization)" SatelliteAssemblies="@(_WasmSatelliteAssemblies)" FilesToIncludeInFileSystem="@(WasmFilesToIncludeInFileSystem)" IcuDataFileNames="@(WasmIcuDataFileNames)" @@ -508,7 +496,6 @@ - @@ -564,7 +551,6 @@ - <_WasmAssembliesInternal Remove="$(_WasmDedupAssembly)"/> diff --git a/src/mono/browser/runtime/assets.ts b/src/mono/browser/runtime/assets.ts index 930f5bb20d184b..9c5290a08f14e5 100644 --- a/src/mono/browser/runtime/assets.ts +++ b/src/mono/browser/runtime/assets.ts @@ -5,7 +5,7 @@ import type { AssetEntryInternal } from "./types/internal"; import cwraps from "./cwraps"; import { mono_wasm_load_icu_data } from "./icu"; -import { Module, globalizationHelpers, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; +import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; import { mono_log_info, mono_log_debug, parseSymbolMapFile } from "./logging"; import { mono_wasm_load_bytes_into_heap_persistent } from "./memory"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; @@ -25,9 +25,7 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A switch (asset.behavior) { case "dotnetwasm": case "js-module-threads": - case "js-module-globalization": case "symbols": - case "segmentation-rules": // do nothing break; case "resource": @@ -106,16 +104,6 @@ export async function instantiate_symbols_asset (pendingAsset: AssetEntryInterna } } -export async function instantiate_segmentation_rules_asset (pendingAsset: AssetEntryInternal): Promise { - try { - const response = await pendingAsset.pendingDownloadInternal!.response; - const json = await response.json(); - globalizationHelpers.setSegmentationRulesFromJson(json); - } catch (error: any) { - mono_log_info(`Error loading static json asset ${pendingAsset.name}: ${JSON.stringify(error)}`); - } -} - export async function wait_for_all_assets () { // wait for all assets in memory await runtimeHelpers.allAssetsInMemory.promise; diff --git a/src/mono/browser/runtime/corebindings.c b/src/mono/browser/runtime/corebindings.c index 15a185133ce36d..e64c5f6d2d81a9 100644 --- a/src/mono/browser/runtime/corebindings.c +++ b/src/mono/browser/runtime/corebindings.c @@ -58,17 +58,8 @@ extern void* mono_wasm_bind_js_import_ST (void *signature); extern void mono_wasm_invoke_jsimport_ST (int function_handle, void *args); #endif /* DISABLE_THREADS */ -// HybridGlobalization -extern char16_t* mono_wasm_change_case (const uint16_t* culture, int32_t cultureLength, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); -extern char16_t* mono_wasm_compare_string (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *resultPtr); -extern char16_t* mono_wasm_starts_with (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool *resultPtr); -extern char16_t* mono_wasm_ends_with (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool *resultPtr); -extern char16_t* mono_wasm_index_of (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool fromBeginning, int *resultPtr); -extern char16_t* mono_wasm_get_calendar_info (const uint16_t* culture, int32_t cultureLength, int32_t calendarId, const uint16_t* result, int32_t resultMaxLength, int *resultLength); -extern char16_t* mono_wasm_get_culture_info (const uint16_t* culture, int32_t cultureLength, const uint16_t* result, int32_t resultMaxLength, int *resultLength); +// JS-based globalization extern char16_t* mono_wasm_get_locale_info (const uint16_t* locale, int32_t localeLength, const uint16_t* culture, int32_t cultureLength, const uint16_t* result, int32_t resultMaxLength, int *resultLength); -extern char16_t* mono_wasm_get_first_day_of_week (const uint16_t* culture, int32_t cultureLength, int *resultPtr); -extern char16_t* mono_wasm_get_first_week_of_year (const uint16_t* culture, int32_t cultureLength, int *resultPtr); void bindings_initialize_internals (void) { @@ -102,17 +93,8 @@ void bindings_initialize_internals (void) mono_add_internal_call ("Interop/Runtime::GetAssemblyExport", mono_wasm_get_assembly_export); mono_add_internal_call ("System.ConsolePal::Clear", mono_wasm_console_clear); - // HybridGlobalization - mono_add_internal_call ("Interop/JsGlobalization::ChangeCase", mono_wasm_change_case); - mono_add_internal_call ("Interop/JsGlobalization::CompareString", mono_wasm_compare_string); - mono_add_internal_call ("Interop/JsGlobalization::StartsWith", mono_wasm_starts_with); - mono_add_internal_call ("Interop/JsGlobalization::EndsWith", mono_wasm_ends_with); - mono_add_internal_call ("Interop/JsGlobalization::IndexOf", mono_wasm_index_of); - mono_add_internal_call ("Interop/JsGlobalization::GetCalendarInfo", mono_wasm_get_calendar_info); + // JS-based globalization mono_add_internal_call ("Interop/JsGlobalization::GetLocaleInfo", mono_wasm_get_locale_info); - mono_add_internal_call ("Interop/JsGlobalization::GetCultureInfo", mono_wasm_get_culture_info); - mono_add_internal_call ("Interop/JsGlobalization::GetFirstDayOfWeek", mono_wasm_get_first_day_of_week); - mono_add_internal_call ("Interop/JsGlobalization::GetFirstWeekOfYear", mono_wasm_get_first_week_of_year); } static MonoAssembly* _mono_wasm_assembly_load (char *assembly_name) diff --git a/src/mono/browser/runtime/dotnet.d.ts b/src/mono/browser/runtime/dotnet.d.ts index 01218688846cba..5bff371447de0f 100644 --- a/src/mono/browser/runtime/dotnet.d.ts +++ b/src/mono/browser/runtime/dotnet.d.ts @@ -368,10 +368,6 @@ type SingleAssetBehaviors = * The javascript module for emscripten. */ | "js-module-native" -/** - * The javascript module for hybrid globalization. - */ - | "js-module-globalization" /** * Typically blazor.boot.json */ @@ -380,10 +376,6 @@ type SingleAssetBehaviors = * The debugging symbols */ | "symbols" -/** - * Load segmentation rules file for Hybrid Globalization. - */ - | "segmentation-rules"; type AssetBehaviors = SingleAssetBehaviors | /** * Load asset as a managed resource assembly. @@ -429,11 +421,7 @@ declare const enum GlobalizationMode { /** * Use user defined icu file. */ - Custom = "custom", - /** - * Operate in hybrid globalization mode with small ICU files, using native platform functions. - */ - Hybrid = "hybrid" + Custom = "custom" } type DotnetModuleConfig = { config?: MonoConfig; diff --git a/src/mono/browser/runtime/es6/dotnet.es6.lib.js b/src/mono/browser/runtime/es6/dotnet.es6.lib.js index 687025478570ed..ad8b0303bbb12d 100644 --- a/src/mono/browser/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/browser/runtime/es6/dotnet.es6.lib.js @@ -77,8 +77,7 @@ function createWasmImportStubsFrom(collection) { // we will replace them with the real implementation in replace_linker_placeholders function injectDependencies() { createWasmImportStubsFrom(methodIndexByName.mono_wasm_imports); - // mono_wasm_hybrid_globalization_imports is empty in non-hybrid globalization mode - createWasmImportStubsFrom(methodIndexByName.mono_wasm_hybrid_globalization_imports); + createWasmImportStubsFrom(methodIndexByName.mono_wasm_js_globalization_imports); #if USE_PTHREADS createWasmImportStubsFrom(methodIndexByName.mono_wasm_threads_imports); diff --git a/src/mono/browser/runtime/exports-binding.ts b/src/mono/browser/runtime/exports-binding.ts index 6ae7a08b95b0b8..5e7472f0a2dea5 100644 --- a/src/mono/browser/runtime/exports-binding.ts +++ b/src/mono/browser/runtime/exports-binding.ts @@ -27,7 +27,7 @@ import { } from "./pthreads"; import { mono_wasm_dump_threads } from "./pthreads/ui-thread"; import { mono_wasm_schedule_synchronization_context } from "./pthreads/shared"; -import { mono_wasm_hybrid_globalization_imports } from "./globalization"; +import { mono_wasm_js_globalization_imports } from "./globalization"; // the JS methods would be visible to EMCC linker and become imports of the WASM module @@ -103,8 +103,8 @@ const wasmImports: Function[] = [ ...mono_wasm_imports, // threading exports, if threading is enabled ...mono_wasm_threads_imports, - // hybrid globalization exports - ...mono_wasm_hybrid_globalization_imports, + // globalization exports + ...mono_wasm_js_globalization_imports, ]; export function replace_linker_placeholders (imports: WebAssembly.Imports) { diff --git a/src/mono/browser/runtime/exports-linker.ts b/src/mono/browser/runtime/exports-linker.ts index 3e1f8c4bd99c7d..6eda7b34ae1b82 100644 --- a/src/mono/browser/runtime/exports-linker.ts +++ b/src/mono/browser/runtime/exports-linker.ts @@ -3,13 +3,13 @@ import { mono_wasm_imports, mono_wasm_threads_imports } from "./exports-binding"; import gitHash from "consts:gitHash"; -import { mono_wasm_hybrid_globalization_imports } from "./globalization"; +import { mono_wasm_js_globalization_imports } from "./globalization"; export function export_linker_indexes_as_code (): string { const indexByName: any = { mono_wasm_imports: {}, mono_wasm_threads_imports: {}, - mono_wasm_hybrid_globalization_imports: {}, + mono_wasm_js_globalization_imports: {}, }; let idx = 0; for (const wi of mono_wasm_imports) { @@ -20,8 +20,8 @@ export function export_linker_indexes_as_code (): string { indexByName.mono_wasm_threads_imports[wi.name] = idx; idx++; } - for (const wi of mono_wasm_hybrid_globalization_imports) { - indexByName.mono_wasm_hybrid_globalization_imports[wi.name] = idx; + for (const wi of mono_wasm_js_globalization_imports) { + indexByName.mono_wasm_js_globalization_imports[wi.name] = idx; idx++; } return ` diff --git a/src/mono/browser/runtime/exports.ts b/src/mono/browser/runtime/exports.ts index 6c2b1fd106596e..23d6d30e28800f 100644 --- a/src/mono/browser/runtime/exports.ts +++ b/src/mono/browser/runtime/exports.ts @@ -7,7 +7,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads"; import WasmEnableSIMD from "consts:wasmEnableSIMD"; import WasmEnableExceptionHandling from "consts:wasmEnableExceptionHandling"; -import { GlobalizationMode, type RuntimeAPI } from "./types"; +import { type RuntimeAPI } from "./types"; import { Module, exportedRuntimeAPI, loaderHelpers, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; import { GlobalObjects, RuntimeHelpers } from "./types/internal"; @@ -19,14 +19,12 @@ import { export_api } from "./export-api"; import { initializeReplacements } from "./polyfills"; import { mono_wasm_stringify_as_error_with_stack } from "./logging"; -import { instantiate_asset, instantiate_symbols_asset, instantiate_segmentation_rules_asset } from "./assets"; +import { instantiate_asset, instantiate_symbols_asset } from "./assets"; import { jiterpreter_dump_stats } from "./jiterpreter"; import { forceDisposeProxies } from "./gc-handles"; import { mono_wasm_dump_threads } from "./pthreads"; import { threads_c_functions as tcwraps } from "./cwraps"; -import { stringToUTF16, stringToUTF16Ptr, utf16ToString, utf16ToStringLoop } from "./strings"; -import { localHeapViewU16, setI32, setU16_local } from "./memory"; export let runtimeList: RuntimeList; @@ -42,22 +40,12 @@ function initializeExports (globalObjects: GlobalObjects): RuntimeAPI { instantiate_asset, jiterpreter_dump_stats, forceDisposeProxies, - instantiate_segmentation_rules_asset, }; if (WasmEnableThreads) { rh.dumpThreads = mono_wasm_dump_threads; rh.mono_wasm_print_thread_dump = () => tcwraps.mono_wasm_print_thread_dump(); } - if (loaderHelpers.config.globalizationMode === GlobalizationMode.Hybrid) { - rh.stringToUTF16 = stringToUTF16; - rh.stringToUTF16Ptr = stringToUTF16Ptr; - rh.utf16ToString = utf16ToString; - rh.utf16ToStringLoop = utf16ToStringLoop; - rh.localHeapViewU16 = localHeapViewU16; - rh.setU16_local = setU16_local; - rh.setI32 = setI32; - } Object.assign(runtimeHelpers, rh); diff --git a/src/mono/browser/runtime/locales-common.ts b/src/mono/browser/runtime/globalization-locale.ts similarity index 83% rename from src/mono/browser/runtime/locales-common.ts rename to src/mono/browser/runtime/globalization-locale.ts index aa3a8ce6c919e7..1b95edfb6878a4 100644 --- a/src/mono/browser/runtime/locales-common.ts +++ b/src/mono/browser/runtime/globalization-locale.ts @@ -3,11 +3,27 @@ import { VoidPtrNull } from "./types/internal"; import { Int32Ptr, VoidPtr } from "./types/emscripten"; -import { OUTER_SEPARATOR, normalizeLocale } from "./hybrid-globalization/helpers"; import { stringToUTF16, stringToUTF16Ptr, utf16ToString } from "./strings"; import { setI32 } from "./memory"; -// functions common for Hybrid Globalization -> true | false : +export const OUTER_SEPARATOR = "##"; + +function normalizeLocale (locale: string | null) { + if (!locale) + return undefined; + try { + locale = locale.toLocaleLowerCase(); + if (locale.includes("zh")) { + // browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-HANS" "zh-HANT", we are helping, otherwise + // it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided" + locale = locale.replace("chs", "HANS").replace("cht", "HANT"); + } + const canonicalLocales = (Intl as any).getCanonicalLocales(locale.replace("_", "-")); + return canonicalLocales.length > 0 ? canonicalLocales[0] : undefined; + } catch { + return undefined; + } +} export function mono_wasm_get_locale_info (culture: number, cultureLength: number, locale: number, localeLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { try { diff --git a/src/mono/browser/runtime/globalization-stubs.ts b/src/mono/browser/runtime/globalization-stubs.ts deleted file mode 100644 index a1a42dc1cd414f..00000000000000 --- a/src/mono/browser/runtime/globalization-stubs.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { globalizationHelpers } from "./globals"; -import { Int32Ptr, VoidPtr } from "./types/emscripten"; -import { VoidPtrNull } from "./types/internal"; - -export function mono_wasm_change_case (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number) : VoidPtr { - if (typeof globalizationHelpers.mono_wasm_change_case === "function") { - return globalizationHelpers.mono_wasm_change_case(culture, cultureLength, src, srcLength, dst, dstLength, toUpper); - } - return VoidPtrNull; -} - -export function mono_wasm_compare_string (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) : VoidPtr { - if (typeof globalizationHelpers.mono_wasm_compare_string === "function") { - return globalizationHelpers.mono_wasm_compare_string(culture, cultureLength, str1, str1Length, str2, str2Length, options, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_starts_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_starts_with === "function") { - return globalizationHelpers.mono_wasm_starts_with(culture, cultureLength, str1, str1Length, str2, str2Length, options, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_ends_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_ends_with === "function") { - return globalizationHelpers.mono_wasm_ends_with(culture, cultureLength, str1, str1Length, str2, str2Length, options, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_index_of (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_index_of === "function") { - return globalizationHelpers.mono_wasm_index_of(culture, cultureLength, needlePtr, needleLength, srcPtr, srcLength, options, fromBeginning, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_get_calendar_info (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_calendar_info === "function") { - return globalizationHelpers.mono_wasm_get_calendar_info(culture, cultureLength, calendarId, dst, dstMaxLength, dstLength); - } - return VoidPtrNull; -} - -export function mono_wasm_get_culture_info (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_culture_info === "function") { - return globalizationHelpers.mono_wasm_get_culture_info(culture, cultureLength, dst, dstMaxLength, dstLength); - } - return VoidPtrNull; -} - -export function mono_wasm_get_first_day_of_week (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_first_day_of_week === "function") { - return globalizationHelpers.mono_wasm_get_first_day_of_week(culture, cultureLength, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_get_first_week_of_year (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_first_week_of_year === "function") { - return globalizationHelpers.mono_wasm_get_first_week_of_year(culture, cultureLength, resultPtr); - } - return VoidPtrNull; -} diff --git a/src/mono/browser/runtime/globalization.ts b/src/mono/browser/runtime/globalization.ts index fe1b95be3ba733..c7fb8eeafce9d5 100644 --- a/src/mono/browser/runtime/globalization.ts +++ b/src/mono/browser/runtime/globalization.ts @@ -1,19 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_change_case, mono_wasm_compare_string, mono_wasm_ends_with, mono_wasm_get_calendar_info, mono_wasm_get_culture_info, mono_wasm_get_first_day_of_week, mono_wasm_get_first_week_of_year, mono_wasm_index_of, mono_wasm_starts_with } from "./globalization-stubs"; -import { mono_wasm_get_locale_info } from "./locales-common"; +import { mono_wasm_get_locale_info } from "./globalization-locale"; -export const mono_wasm_hybrid_globalization_imports = [ - mono_wasm_change_case, - mono_wasm_compare_string, - mono_wasm_starts_with, - mono_wasm_ends_with, - mono_wasm_index_of, - mono_wasm_get_calendar_info, - mono_wasm_get_culture_info, - mono_wasm_get_first_day_of_week, - mono_wasm_get_first_week_of_year, - // used by both: non-HG and HG: +// JS-based globalization support for WebAssembly + +export const mono_wasm_js_globalization_imports = [ mono_wasm_get_locale_info, ]; diff --git a/src/mono/browser/runtime/globals.ts b/src/mono/browser/runtime/globals.ts index f6b8aa1f548f94..e1eeed5ddce1d5 100644 --- a/src/mono/browser/runtime/globals.ts +++ b/src/mono/browser/runtime/globals.ts @@ -9,7 +9,7 @@ import gitHash from "consts:gitHash"; import { RuntimeAPI } from "./types/index"; -import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers, DotnetModuleInternal, PromiseAndController, EmscriptenBuildOptions, GCHandle, GlobalizationHelpers } from "./types/internal"; +import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers, DotnetModuleInternal, PromiseAndController, EmscriptenBuildOptions, GCHandle } from "./types/internal"; import { mono_log_error } from "./logging"; // these are our public API (except internal) @@ -29,7 +29,6 @@ export let ENVIRONMENT_IS_PTHREAD: boolean; export let exportedRuntimeAPI: RuntimeAPI = null as any; export let runtimeHelpers: RuntimeHelpers = null as any; export let loaderHelpers: LoaderHelpers = null as any; -export let globalizationHelpers: GlobalizationHelpers = null as any; export let _runtimeModuleLoaded = false; // please keep it in place also as rollup guard @@ -54,7 +53,6 @@ export function setRuntimeGlobals (globalObjects: GlobalObjects) { INTERNAL = globalObjects.internal; runtimeHelpers = globalObjects.runtimeHelpers; loaderHelpers = globalObjects.loaderHelpers; - globalizationHelpers = globalObjects.globalizationHelpers; exportedRuntimeAPI = globalObjects.api; const rh: Partial = { diff --git a/src/mono/browser/runtime/hybrid-globalization/calendar.ts b/src/mono/browser/runtime/hybrid-globalization/calendar.ts deleted file mode 100644 index fd211755469d3c..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/calendar.ts +++ /dev/null @@ -1,364 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/* eslint-disable no-inner-declarations */ -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { INNER_SEPARATOR, OUTER_SEPARATOR } from "./helpers"; - -const MONTH_CODE = "MMMM"; -const YEAR_CODE = "yyyy"; -const DAY_CODE = "d"; -const WEEKDAY_CODE = "dddd"; -const keyWords = [MONTH_CODE, YEAR_CODE, DAY_CODE, WEEKDAY_CODE]; - -// this function joins all calendar info with OUTER_SEPARATOR into one string and returns it back to managed code -export function mono_wasm_get_calendar_info (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const locale = cultureName ? cultureName : undefined; - const calendarInfo = { - EnglishName: "", - YearMonth: "", - MonthDay: "", - LongDates: "", - ShortDates: "", - EraNames: "", - AbbreviatedEraNames: "", - DayNames: "", - AbbreviatedDayNames: "", - ShortestDayNames: "", - MonthNames: "", - AbbreviatedMonthNames: "", - MonthGenitiveNames: "", - AbbrevMonthGenitiveNames: "", - }; - const date = new Date(999, 10, 22); // Fri Nov 22 0999 00:00:00 GMT+0124 (Central European Standard Time) - calendarInfo.EnglishName = getCalendarName(locale); - const dayNames = getDayNames(locale); - calendarInfo.DayNames = dayNames.long.join(INNER_SEPARATOR); - calendarInfo.AbbreviatedDayNames = dayNames.abbreviated.join(INNER_SEPARATOR); - calendarInfo.ShortestDayNames = dayNames.shortest.join(INNER_SEPARATOR); - const monthNames = getMonthNames(locale); - calendarInfo.MonthNames = monthNames.long.join(INNER_SEPARATOR); - calendarInfo.AbbreviatedMonthNames = monthNames.abbreviated.join(INNER_SEPARATOR); - calendarInfo.MonthGenitiveNames = monthNames.longGenitive.join(INNER_SEPARATOR); - calendarInfo.AbbrevMonthGenitiveNames = monthNames.abbreviatedGenitive.join(INNER_SEPARATOR); - calendarInfo.YearMonth = getMonthYearPattern(locale, date); - calendarInfo.MonthDay = getMonthDayPattern(locale, date); - calendarInfo.ShortDates = getShortDatePattern(locale); - calendarInfo.LongDates = getLongDatePattern(locale, date); - const eraNames = getEraNames(date, locale, calendarId); - calendarInfo.EraNames = eraNames.eraNames; - calendarInfo.AbbreviatedEraNames = eraNames.abbreviatedEraNames; - - const result = Object.values(calendarInfo).join(OUTER_SEPARATOR); - if (result.length > dstMaxLength) { - throw new Error(`Calendar info exceeds length of ${dstMaxLength}.`); - } - runtimeHelpers.stringToUTF16(dst, dst + 2 * result.length, result); - runtimeHelpers.setI32(dstLength, result.length); - return VoidPtrNull; - } catch (ex: any) { - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function getCalendarName (locale: any) { - const calendars = getCalendarInfo(locale); - if (!calendars || calendars.length == 0) - return ""; - return calendars[0]; -} - -function getCalendarInfo (locale: string) { - try { - // most tools have it implemented as a property - return (new Intl.Locale(locale) as any).calendars; - } catch { - try { - // but a few use methods, which is the preferred way - return (new Intl.Locale(locale) as any).getCalendars(); - } catch { - return undefined; - } - } -} - -function getMonthYearPattern (locale: string | undefined, date: Date): string { - let pattern = date.toLocaleDateString(locale, { year: "numeric", month: "long" }).toLowerCase(); - // pattern has month name as string or as number - const monthName = date.toLocaleString(locale, { month: "long" }).toLowerCase().trim(); - if (monthName.charAt(monthName.length - 1) == "\u6708") { - // Chineese-like patterns: - return "yyyy\u5e74M\u6708"; - } - pattern = pattern.replace(monthName, MONTH_CODE); - pattern = pattern.replace("999", YEAR_CODE); - // sometimes the number is localized and the above does not have an effect - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - return pattern.replace(yearStr, YEAR_CODE); -} - -function getMonthDayPattern (locale: string | undefined, date: Date): string { - let pattern = date.toLocaleDateString(locale, { month: "long", day: "numeric" }).toLowerCase(); - // pattern has month name as string or as number - const monthName = date.toLocaleString(locale, { month: "long" }).toLowerCase().trim(); - if (monthName.charAt(monthName.length - 1) == "\u6708") { - // Chineese-like patterns: - return "M\u6708d\u65e5"; - } - const formatWithoutMonthName = new Intl.DateTimeFormat(locale, { day: "numeric" }); - const replacedMonthName = getGenitiveForName(date, pattern, monthName, formatWithoutMonthName); - pattern = pattern.replace(replacedMonthName, MONTH_CODE); - pattern = pattern.replace("22", DAY_CODE); - const dayStr = formatWithoutMonthName.format(date); - return pattern.replace(dayStr, DAY_CODE); -} - -function getShortDatePattern (locale: string | undefined): string { - if (locale?.substring(0, 2) == "fa") { - // persian calendar is shifted and it has no lapping dates with - // arabic and gregorian calendars, so that both day and month would be < 10 - return "yyyy/M/d"; - } - const year = 2014; - const month = 1; - const day = 2; - const date = new Date(year, month - 1, day); // arabic: 1/3/1435 - const longYearStr = "2014"; - const shortYearStr = "14"; - const longMonthStr = "01"; - const shortMonthStr = "1"; - const longDayStr = "02"; - const shortDayStr = "2"; - let pattern = date.toLocaleDateString(locale, { dateStyle: "short" }); - // each date part might be in localized numbers or standard arabic numbers - // toLocaleDateString returns not compatible data, - // e.g. { dateStyle: "short" } sometimes contains localized year number - // while { year: "numeric" } contains non-localized year number and vice versa - if (pattern.includes(shortYearStr)) { - pattern = pattern.replace(longYearStr, YEAR_CODE); - pattern = pattern.replace(shortYearStr, YEAR_CODE); - } else { - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - const yearStrShort = yearStr.substring(yearStr.length - 2, yearStr.length); - pattern = pattern.replace(yearStr, YEAR_CODE); - if (yearStrShort) - pattern = pattern.replace(yearStrShort, YEAR_CODE); - } - - if (pattern.includes(shortMonthStr)) { - pattern = pattern.replace(longMonthStr, "MM"); - pattern = pattern.replace(shortMonthStr, "M"); - } else { - const monthStr = date.toLocaleDateString(locale, { month: "numeric" }); - const localizedMonthCode = monthStr.length == 1 ? "M" : "MM"; - pattern = pattern.replace(monthStr, localizedMonthCode); - } - - if (pattern.includes(shortDayStr)) { - pattern = pattern.replace(longDayStr, "dd"); - pattern = pattern.replace(shortDayStr, "d"); - } else { - const dayStr = date.toLocaleDateString(locale, { day: "numeric" }); - const localizedDayCode = dayStr.length == 1 ? "d" : "dd"; - pattern = pattern.replace(dayStr, localizedDayCode); - } - return pattern; -} - -function getLongDatePattern (locale: string | undefined, date: Date): string { - if (locale == "th-TH") { - // cannot be caught with regexes - return "ddddที่ d MMMM g yyyy"; - } - let pattern = new Intl.DateTimeFormat(locale, { weekday: "long", year: "numeric", month: "long", day: "numeric" }).format(date).toLowerCase(); - const monthName = date.toLocaleString(locale, { month: "long" }).trim().toLowerCase(); - - // pattern has month name as string or as number - const monthSuffix = monthName.charAt(monthName.length - 1); - if (monthSuffix == "\u6708" || monthSuffix == "\uc6d4") { - // Asian-like patterns: - const shortMonthName = date.toLocaleString(locale, { month: "short" }); - pattern = pattern.replace(shortMonthName, `M${monthSuffix}`); - } else { - const replacedMonthName = getGenitiveForName(date, pattern, monthName, new Intl.DateTimeFormat(locale, { weekday: "long", year: "numeric", day: "numeric" })); - pattern = pattern.replace(replacedMonthName, MONTH_CODE); - } - pattern = pattern.replace("999", YEAR_CODE); - // sometimes the number is localized and the above does not have an effect, - // so additionally, we need to do: - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - pattern = pattern.replace(yearStr, YEAR_CODE); - const weekday = date.toLocaleDateString(locale, { weekday: "long" }).toLowerCase(); - const replacedWeekday = getGenitiveForName(date, pattern, weekday, new Intl.DateTimeFormat(locale, { year: "numeric", month: "long", day: "numeric" })); - pattern = pattern.replace(replacedWeekday, WEEKDAY_CODE); - pattern = pattern.replace("22", DAY_CODE); - const dayStr = date.toLocaleDateString(locale, { day: "numeric" }); // should we replace it for localized digits? - pattern = pattern.replace(dayStr, DAY_CODE); - return wrapSubstrings(pattern, locale); -} - -function getGenitiveForName (date: Date, pattern: string, name: string, formatWithoutName: Intl.DateTimeFormat) { - let genitiveName = name; - const nameStart = pattern.indexOf(name); - if (nameStart == -1 || - // genitive month name can include monthName and monthName can include spaces, e.g. "tháng 11":, so we cannot use pattern.includes() or pattern.split(" ").includes() - (nameStart != -1 && pattern.length > nameStart + name.length && pattern[nameStart + name.length] != " " && pattern[nameStart + name.length] != "," && pattern[nameStart + name.length] != "\u060c")) { - // needs to be in Genitive form to be useful - // e.g. - // pattern = '999 m. lapkričio 22 d., šeštadienis', - // patternWithoutName = '999 2, šeštadienis', - // name = 'lapkritis' - // genitiveName = 'lapkričio' - const patternWithoutName = formatWithoutName.format(date).toLowerCase(); - genitiveName = pattern.split(/,| /).filter(x => !patternWithoutName.split(/,| /).includes(x) && x[0] == name[0])[0]; - } - return genitiveName; -} - -function getDayNames (locale: string | undefined) : { long: string[], abbreviated: string[], shortest: string[] } { - const weekDay = new Date(2023, 5, 25); // Sunday - const dayNames = []; - const dayNamesAbb = []; - const dayNamesSS = []; - for (let i = 0; i < 7; i++) { - dayNames[i] = weekDay.toLocaleDateString(locale, { weekday: "long" }); - dayNamesAbb[i] = weekDay.toLocaleDateString(locale, { weekday: "short" }); - dayNamesSS[i] = weekDay.toLocaleDateString(locale, { weekday: "narrow" }); - weekDay.setDate(weekDay.getDate() + 1); - } - return { long: dayNames, abbreviated: dayNamesAbb, shortest: dayNamesSS }; -} - -function getMonthNames (locale: string | undefined) : { long: string[], abbreviated: string[], longGenitive: string[], abbreviatedGenitive: string[] } { - // some calendars have the first month on non-0 index in JS - // first month: Muharram ("ar") or Farwardin ("fa") or January - const localeLang = locale ? locale.split("-")[0] : ""; - const firstMonthShift = localeLang == "ar" ? 8 : localeLang == "fa" ? 3 : 0; - const date = new Date(2021, firstMonthShift, 1); - const months: string[] = []; - const monthsAbb: string[] = []; - const monthsGen: string[] = []; - const monthsAbbGen: string[] = []; - let isChineeseStyle, isShortFormBroken; - for (let i = firstMonthShift; i < 12 + firstMonthShift; i++) { - const monthCnt = i % 12; - date.setMonth(monthCnt); - - const monthNameLong = date.toLocaleDateString(locale, { month: "long" }); - const monthNameShort = date.toLocaleDateString(locale, { month: "short" }); - months[i - firstMonthShift] = monthNameLong; - monthsAbb[i - firstMonthShift] = monthNameShort; - // for Genitive forms: - isChineeseStyle = isChineeseStyle ?? monthNameLong.charAt(monthNameLong.length - 1) == "\u6708"; - if (isChineeseStyle) { - // for Chinese-like calendar's Genitive = Nominative - monthsGen[i - firstMonthShift] = monthNameLong; - monthsAbbGen[i - firstMonthShift] = monthNameShort; - continue; - } - const formatWithoutMonthName = new Intl.DateTimeFormat(locale, { day: "numeric" }); - const monthWithDayLong = date.toLocaleDateString(locale, { month: "long", day: "numeric" }); - monthsGen[i - firstMonthShift] = getGenitiveForName(date, monthWithDayLong, monthNameLong, formatWithoutMonthName); - isShortFormBroken = isShortFormBroken ?? /^\d+$/.test(monthNameShort); - if (isShortFormBroken) { - // for buggy locales e.g. lt-LT, short month contains only number instead of string - // we leave Genitive = Nominative - monthsAbbGen[i - firstMonthShift] = monthNameShort; - continue; - } - const monthWithDayShort = date.toLocaleDateString(locale, { month: "short", day: "numeric" }); - monthsAbbGen[i - firstMonthShift] = getGenitiveForName(date, monthWithDayShort, monthNameShort, formatWithoutMonthName); - } - return { long: months, abbreviated: monthsAbb, longGenitive: monthsGen, abbreviatedGenitive: monthsAbbGen }; -} - -// .NET expects that only the Japanese calendars have more than 1 era. -// So for other calendars, only return the latest era. -function getEraNames (date: Date, locale: string | undefined, calendarId: number) : { eraNames: string, abbreviatedEraNames: string} { - if (shouldBePopulatedByManagedCode(calendarId)) { - // managed code already handles these calendars, - // so empty strings will get overwritten in - // InitializeEraNames/InitializeAbbreviatedEraNames - return { - eraNames: "", - abbreviatedEraNames: "" - }; - } - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - const dayStr = date.toLocaleDateString(locale, { day: "numeric" }); - const eraDate = date.toLocaleDateString(locale, { era: "short" }); - const shortEraDate = date.toLocaleDateString(locale, { era: "narrow" }); - - const eraDateParts = eraDate.includes(yearStr) ? - getEraDateParts(yearStr) : - getEraDateParts(date.getFullYear().toString()); - - return { - eraNames: getEraFromDateParts(eraDateParts.eraDateParts, eraDateParts.ignoredPart), - abbreviatedEraNames: getEraFromDateParts(eraDateParts.abbrEraDateParts, eraDateParts.ignoredPart) - }; - - function shouldBePopulatedByManagedCode (calendarId: number) { - return (calendarId > 1 && calendarId < 15) || calendarId == 22 || calendarId == 23; - } - - function getEraFromDateParts (dateParts: string[], ignoredPart: string) : string { - const regex = new RegExp(`^((?!${ignoredPart}|[0-9]).)*$`); - const filteredEra = dateParts.filter(part => regex.test(part)); - if (filteredEra.length == 0) - throw new Error(`Internal error, era for locale ${locale} was in non-standard format.`); - return filteredEra[0].trim(); - } - - function getEraDateParts (yearStr: string) { - if (eraDate.startsWith(yearStr) || eraDate.endsWith(yearStr)) { - return { - eraDateParts: eraDate.split(dayStr), - abbrEraDateParts: shortEraDate.split(dayStr), - ignoredPart: yearStr, - }; - } - return { - eraDateParts: eraDate.split(yearStr), - abbrEraDateParts: shortEraDate.split(yearStr), - ignoredPart: dayStr, - }; - } -} - -// wraps all substrings in the format in quotes, except for key words -// transform e.g. "dddd, d MMMM yyyy г." into "dddd, d MMMM yyyy 'г'." -function wrapSubstrings (str: string, locale: string | undefined) { - const words = str.split(/\s+/); - // locales that write date nearly without spaces should not have format parts quoted - "ja", "zh" - // "ko" format parts should not be quoted but processing it would overcomplicate the logic - if (words.length <= 2 || locale?.startsWith("ko")) { - return str; - } - - for (let i = 0; i < words.length; i++) { - if (!keyWords.includes(words[i].replace(",", "")) && - !keyWords.includes(words[i].replace(".", "")) && - !keyWords.includes(words[i].replace("\u060c", "")) && - !keyWords.includes(words[i].replace("\u05d1", ""))) { - if (words[i].endsWith(".,")) { - // if the "word" appears twice, then the occurence with punctuation is not a code but fixed part of the format - // see: "hu-HU" vs "lt-LT" format - const wordNoPuctuation = words[i].slice(0, -2); - if (words.filter(x => x == wordNoPuctuation).length == 1) - words[i] = `'${words[i].slice(0, -2)}'.,`; - } else if (words[i].endsWith(".")) { - words[i] = `'${words[i].slice(0, -1)}'.`; - } else if (words[i].endsWith(",")) { - words[i] = `'${words[i].slice(0, -1)}',`; - } else { - words[i] = `'${words[i]}'`; - } - } - } - return words.join(" "); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/change-case.ts b/src/mono/browser/runtime/hybrid-globalization/change-case.ts deleted file mode 100644 index 0024b5b45d5d15..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/change-case.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { VoidPtr } from "../types/emscripten"; -import { isSurrogate } from "./helpers"; - -export function mono_wasm_change_case (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - if (!cultureName) - throw new Error("Cannot change case, the culture name is null."); - const input = runtimeHelpers.utf16ToStringLoop(src, src + 2 * srcLength); - const result = toUpper ? input.toLocaleUpperCase(cultureName) : input.toLocaleLowerCase(cultureName); - - if (result.length <= input.length) { - runtimeHelpers.stringToUTF16(dst, dst + 2 * dstLength, result); - return VoidPtrNull; - } - // workaround to maintain the ICU-like behavior - const heapI16 = runtimeHelpers.localHeapViewU16(); - let jump = 1; - if (toUpper) { - for (let i = 0; i < input.length; i += jump) { - // surrogate parts have to enter ToUpper/ToLower together to give correct output - if (isSurrogate(input, i)) { - jump = 2; - const surrogate = input.substring(i, i + 2); - const upperSurrogate = surrogate.toLocaleUpperCase(cultureName); - const appendedSurrogate = upperSurrogate.length > 2 ? surrogate : upperSurrogate; - appendSurrogateToMemory(heapI16, dst, appendedSurrogate, i); - - } else { - jump = 1; - const upperChar = input[i].toLocaleUpperCase(cultureName); - const appendedChar = upperChar.length > 1 ? input[i] : upperChar; - runtimeHelpers.setU16_local(heapI16, dst + i * 2, appendedChar.charCodeAt(0)); - } - } - } else { - for (let i = 0; i < input.length; i += jump) { - // surrogate parts have to enter ToUpper/ToLower together to give correct output - if (isSurrogate(input, i)) { - jump = 2; - const surrogate = input.substring(i, i + 2); - const upperSurrogate = surrogate.toLocaleLowerCase(cultureName); - const appendedSurrogate = upperSurrogate.length > 2 ? surrogate : upperSurrogate; - appendSurrogateToMemory(heapI16, dst, appendedSurrogate, i); - } else { - jump = 1; - const lowerChar = input[i].toLocaleLowerCase(cultureName); - const appendedChar = lowerChar.length > 1 ? input[i] : lowerChar; - runtimeHelpers.setU16_local(heapI16, dst + i * 2, appendedChar.charCodeAt(0)); - } - } - } - return VoidPtrNull; - } catch (ex: any) { - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function appendSurrogateToMemory (heapI16: Uint16Array, dst: number, surrogate: string, idx: number) { - runtimeHelpers.setU16_local(heapI16, dst + idx * 2, surrogate.charCodeAt(0)); - runtimeHelpers.setU16_local(heapI16, dst + (idx + 1) * 2, surrogate.charCodeAt(1)); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/collations.ts b/src/mono/browser/runtime/hybrid-globalization/collations.ts deleted file mode 100644 index 026cd942ea99e0..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/collations.ts +++ /dev/null @@ -1,268 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { GraphemeSegmenter } from "./grapheme-segmenter"; - -const COMPARISON_ERROR = -2; -const INDEXING_ERROR = -1; -let graphemeSegmenterCached: GraphemeSegmenter | null; - -export function mono_wasm_compare_string (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const string1 = runtimeHelpers.utf16ToString(str1, (str1 + 2 * str1Length)); - const string2 = runtimeHelpers.utf16ToString(str2, (str2 + 2 * str2Length)); - const compareOptions = (options & 0x3f); - const locale = cultureName ? cultureName : undefined; - const result = compareStrings(string1, string2, locale, compareOptions); - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, COMPARISON_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_starts_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const prefix = decodeToCleanString(str2, str2Length); - // no need to look for an empty string - if (prefix.length == 0) { - runtimeHelpers.setI32(resultPtr, 1); // true - return VoidPtrNull; - } - - const source = decodeToCleanString(str1, str1Length); - if (source.length < prefix.length) { - runtimeHelpers.setI32(resultPtr, 0); // false - return VoidPtrNull; - } - const sourceOfPrefixLength = source.slice(0, prefix.length); - - const casePicker = (options & 0x3f); - const locale = cultureName ? cultureName : undefined; - const cmpResult = compareStrings(sourceOfPrefixLength, prefix, locale, casePicker); - const result = cmpResult === 0 ? 1 : 0; // equals ? true : false - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, INDEXING_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_ends_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const suffix = decodeToCleanString(str2, str2Length); - if (suffix.length == 0) { - runtimeHelpers.setI32(resultPtr, 1); // true - return VoidPtrNull; - } - - const source = decodeToCleanString(str1, str1Length); - const diff = source.length - suffix.length; - if (diff < 0) { - runtimeHelpers.setI32(resultPtr, 0); // false - return VoidPtrNull; - } - const sourceOfSuffixLength = source.slice(diff, source.length); - - const casePicker = (options & 0x3f); - const locale = cultureName ? cultureName : undefined; - const cmpResult = compareStrings(sourceOfSuffixLength, suffix, locale, casePicker); - const result = cmpResult === 0 ? 1 : 0; // equals ? true : false - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, INDEXING_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_index_of (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr): VoidPtr { - try { - const needle = decodeToCleanStringForIndexing(needlePtr, needleLength); - // no need to look for an empty string - if (cleanString(needle).length == 0) { - runtimeHelpers.setI32(resultPtr, fromBeginning ? 0 : srcLength); - return VoidPtrNull; - } - - const source = decodeToCleanStringForIndexing(srcPtr, srcLength); - // no need to look in an empty string - if (cleanString(source).length == 0) { - runtimeHelpers.setI32(resultPtr, fromBeginning ? 0 : srcLength); - return VoidPtrNull; - } - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const locale = cultureName ? cultureName : undefined; - const casePicker = (options & 0x3f); - let result = -1; - - const graphemeSegmenter = graphemeSegmenterCached || (graphemeSegmenterCached = new GraphemeSegmenter()); - const needleSegments = []; - let needleIdx = 0; - - // Grapheme segmentation of needle string - while (needleIdx < needle.length) { - const needleGrapheme = graphemeSegmenter.nextGrapheme(needle, needleIdx); - needleSegments.push(needleGrapheme); - needleIdx += needleGrapheme.length; - } - - let srcIdx = 0; - while (srcIdx < source.length) { - const srcGrapheme = graphemeSegmenter.nextGrapheme(source, srcIdx); - srcIdx += srcGrapheme.length; - - if (!checkMatchFound(srcGrapheme, needleSegments[0], locale, casePicker)) { - continue; - } - - let j; - let srcNextIdx = srcIdx; - for (j = 1; j < needleSegments.length; j++) { - const srcGrapheme = graphemeSegmenter.nextGrapheme(source, srcNextIdx); - - if (!checkMatchFound(srcGrapheme, needleSegments[j], locale, casePicker)) { - break; - } - srcNextIdx += srcGrapheme.length; - } - if (j === needleSegments.length) { - result = srcIdx - srcGrapheme.length; - if (fromBeginning) - break; - } - } - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, INDEXING_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } - - function checkMatchFound (str1: string, str2: string, locale: string | undefined, casePicker: number): boolean { - return compareStrings(str1, str2, locale, casePicker) === 0; - } -} - -function compareStrings (string1: string, string2: string, locale: string | undefined, compareOptions: number): number { - let options: Intl.CollatorOptions | undefined = undefined; - - const numericOrderingFlag = 0x20; - if (compareOptions & numericOrderingFlag) { - options = { numeric: true }; - } - - switch (compareOptions & (~numericOrderingFlag)) { - case 0: - // 0: None - default algorithm for the platform OR - // StringSort - for ICU it gives the same result as None, see: https://github.com/dotnet/dotnet-api-docs/issues - // does not work for "ja" - if (locale && locale.split("-")[0] === "ja") - return COMPARISON_ERROR; - return string1.localeCompare(string2, locale, options); // a ≠ b, a ≠ á, a ≠ A - case 8: - // 8: IgnoreKanaType works only for "ja" - if (locale && locale.split("-")[0] !== "ja") - return COMPARISON_ERROR; - return string1.localeCompare(string2, locale, options); // a ≠ b, a ≠ á, a ≠ A - case 1: - // 1: IgnoreCase - string1 = string1.toLocaleLowerCase(locale); - string2 = string2.toLocaleLowerCase(locale); - return string1.localeCompare(string2, locale, options); // a ≠ b, a ≠ á, a ≠ A - case 4: - case 12: - // 4: IgnoreSymbols - // 12: IgnoreKanaType | IgnoreSymbols - return string1.localeCompare(string2, locale, { ignorePunctuation: true, ...options }); // by default ignorePunctuation: false - case 5: - // 5: IgnoreSymbols | IgnoreCase - string1 = string1.toLocaleLowerCase(locale); - string2 = string2.toLocaleLowerCase(locale); - return string1.localeCompare(string2, locale, { ignorePunctuation: true, ...options }); // a ≠ b, a ≠ á, a ≠ A - case 9: - // 9: IgnoreKanaType | IgnoreCase - return string1.localeCompare(string2, locale, { sensitivity: "accent", ...options }); // a ≠ b, a ≠ á, a = A - case 10: - // 10: IgnoreKanaType | IgnoreNonSpace - return string1.localeCompare(string2, locale, { sensitivity: "case", ...options }); // a ≠ b, a = á, a ≠ A - case 11: - // 11: IgnoreKanaType | IgnoreNonSpace | IgnoreCase - return string1.localeCompare(string2, locale, { sensitivity: "base", ...options }); // a ≠ b, a = á, a = A - case 13: - // 13: IgnoreKanaType | IgnoreCase | IgnoreSymbols - return string1.localeCompare(string2, locale, { sensitivity: "accent", ignorePunctuation: true, ...options }); // a ≠ b, a ≠ á, a = A - case 14: - // 14: IgnoreKanaType | IgnoreSymbols | IgnoreNonSpace - return string1.localeCompare(string2, locale, { sensitivity: "case", ignorePunctuation: true, ...options });// a ≠ b, a = á, a ≠ A - case 15: - // 15: IgnoreKanaType | IgnoreSymbols | IgnoreNonSpace | IgnoreCase - return string1.localeCompare(string2, locale, { sensitivity: "base", ignorePunctuation: true, ...options }); // a ≠ b, a = á, a = A - case 2: - case 3: - case 6: - case 7: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - default: - // 2: IgnoreNonSpace - // 3: IgnoreNonSpace | IgnoreCase - // 6: IgnoreSymbols | IgnoreNonSpace - // 7: IgnoreSymbols | IgnoreNonSpace | IgnoreCase - // 16: IgnoreWidth - // 17: IgnoreWidth | IgnoreCase - // 18: IgnoreWidth | IgnoreNonSpace - // 19: IgnoreWidth | IgnoreNonSpace | IgnoreCase - // 20: IgnoreWidth | IgnoreSymbols - // 21: IgnoreWidth | IgnoreSymbols | IgnoreCase - // 22: IgnoreWidth | IgnoreSymbols | IgnoreNonSpace - // 23: IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase - // 24: IgnoreKanaType | IgnoreWidth - // 25: IgnoreKanaType | IgnoreWidth | IgnoreCase - // 26: IgnoreKanaType | IgnoreWidth | IgnoreNonSpace - // 27: IgnoreKanaType | IgnoreWidth | IgnoreNonSpace | IgnoreCase - // 28: IgnoreKanaType | IgnoreWidth | IgnoreSymbols - // 29: IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreCase - // 30: IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace - // 31: IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase - throw new Error(`Invalid comparison option. Option=${compareOptions}`); - } -} - -function decodeToCleanString (strPtr: number, strLen: number) { - const str = runtimeHelpers.utf16ToString(strPtr, (strPtr + 2 * strLen)); - return cleanString(str); -} - -function cleanString (str: string) { - const nStr = str.normalize(); - return nStr.replace(/[\u200B-\u200D\uFEFF\0\u00AD]/g, ""); -} - -// in ICU indexing only SoftHyphen is weightless -function decodeToCleanStringForIndexing (strPtr: number, strLen: number) { - const str = runtimeHelpers.utf16ToString(strPtr, (strPtr + 2 * strLen)); - return str.replace(/[\u00AD]/g, ""); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/culture-info.ts b/src/mono/browser/runtime/hybrid-globalization/culture-info.ts deleted file mode 100644 index b62b50854408d4..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/culture-info.ts +++ /dev/null @@ -1,139 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { OUTER_SEPARATOR, normalizeLocale } from "./helpers"; - -const NO_PREFIX_24H = "H"; -const PREFIX_24H = "HH"; -const NO_PREFIX_12H = "h"; -const PREFIX_12H = "hh"; -const SECONDS_CODE = "ss"; -const MINUTES_CODE = "mm"; -const DESIGNATOR_CODE = "tt"; -// Note: wrapSubstrings -// The character "h" can be ambiguous as it might represent an hour code hour code and a fixed (quoted) part of the format. -// Special Case for "fr-CA": Always recognize "HH" as a keyword and do not quote it, to avoid formatting issues. -const keyWords = [SECONDS_CODE, MINUTES_CODE, DESIGNATOR_CODE, PREFIX_24H]; - -export function mono_wasm_get_culture_info (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const cultureInfo = { - AmDesignator: "", - PmDesignator: "", - LongTimePattern: "", - ShortTimePattern: "" - }; - const canonicalLocale = normalizeLocale(cultureName); - const designators = getAmPmDesignators(canonicalLocale); - cultureInfo.AmDesignator = designators.am; - cultureInfo.PmDesignator = designators.pm; - cultureInfo.LongTimePattern = getLongTimePattern(canonicalLocale, designators); - cultureInfo.ShortTimePattern = getShortTimePattern(cultureInfo.LongTimePattern); - const result = Object.values(cultureInfo).join(OUTER_SEPARATOR); - if (result.length > dstMaxLength) { - throw new Error(`Culture info exceeds length of ${dstMaxLength}.`); - } - runtimeHelpers.stringToUTF16(dst, dst + 2 * result.length, result); - runtimeHelpers.setI32(dstLength, result.length); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(dstLength, -1); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function getAmPmDesignators (locale: any) { - const pmTime = new Date("August 19, 1975 12:15:33"); // do not change, some PM hours result in hour digits change, e.g. 13 -> 01 or 1 - const amTime = new Date("August 19, 1975 11:15:33"); // do not change, some AM hours result in hour digits change, e.g. 9 -> 09 - const pmDesignator = getDesignator(pmTime, locale); - const amDesignator = getDesignator(amTime, locale); - return { - am: amDesignator, - pm: pmDesignator - }; -} - -function getDesignator (time: Date, locale: string) { - let withDesignator = time.toLocaleTimeString(locale, { hourCycle: "h12" }); - const localizedZero = (0).toLocaleString(locale); - if (withDesignator.includes(localizedZero)) { - // in v8>=11.8 "12" changes to "0" for ja-JP - const localizedTwelve = (12).toLocaleString(locale); - withDesignator = withDesignator.replace(localizedZero, localizedTwelve); - } - const withoutDesignator = time.toLocaleTimeString(locale, { hourCycle: "h24" }); - const designator = withDesignator.replace(withoutDesignator, "").trim(); - if (new RegExp("[0-9]$").test(designator)) { - const designatorParts = withDesignator.split(" ").filter(part => new RegExp("^((?![0-9]).)*$").test(part)); - if (!designatorParts || designatorParts.length == 0) - return ""; - return designatorParts.join(" "); - } - return designator; -} - -function getLongTimePattern (locale: string | undefined, designators: any): string { - const hourIn24Format = 18; // later hours than 18 have night designators in some locales (instead of AM designator) - const hourIn12Format = 6; - const localizedHour24 = (hourIn24Format).toLocaleString(locale); // not all locales use arabic numbers - const localizedHour12 = (hourIn12Format).toLocaleString(locale); - const pmTime = new Date(`August 19, 1975 ${hourIn24Format}:15:30`); // in the comments, en-US locale is used: - const shortTime = new Intl.DateTimeFormat(locale, { timeStyle: "medium" }); - const shortPmStyle = shortTime.format(pmTime); // 12:15:30 PM - const minutes = pmTime.toLocaleTimeString(locale, { minute: "numeric" }); // 15 - const seconds = pmTime.toLocaleTimeString(locale, { second: "numeric" }); // 30 - let pattern = shortPmStyle.replace(designators.pm, DESIGNATOR_CODE).replace(minutes, MINUTES_CODE).replace(seconds, SECONDS_CODE); // 12:mm:ss tt - - const isISOStyle = pattern.includes(localizedHour24); // 24h or 12h pattern? - const localized0 = (0).toLocaleString(locale); - const hour12WithPrefix = `${localized0}${localizedHour12}`; // 06 - const amTime = new Date(`August 19, 1975 ${hourIn12Format}:15:30`); - const h12Style = shortTime.format(amTime); - let hourPattern; - if (isISOStyle) { // 24h - const hasPrefix = h12Style.includes(hour12WithPrefix); - hourPattern = hasPrefix ? PREFIX_24H : NO_PREFIX_24H; - pattern = pattern.replace(localizedHour24, hourPattern); - } else { // 12h - const hasPrefix = h12Style.includes(hour12WithPrefix); - hourPattern = hasPrefix ? PREFIX_12H : NO_PREFIX_12H; - pattern = pattern.replace(hasPrefix ? hour12WithPrefix : localizedHour12, hourPattern); - } - return wrapSubstrings(pattern); -} - -function getShortTimePattern (pattern: string): string { - // remove seconds: - // short dotnet pattern does not contain seconds while JS's pattern always contains them - const secondsIdx = pattern.indexOf(SECONDS_CODE); - if (secondsIdx > 0) { - const secondsWithSeparator = `${pattern[secondsIdx - 1]}${SECONDS_CODE}`; - // en-US: 12:mm:ss tt -> 12:mm tt; - // fr-CA: 12 h mm min ss s -> 12 h mm min s - const shortPatternNoSecondsDigits = pattern.replace(secondsWithSeparator, ""); - if (shortPatternNoSecondsDigits.length > secondsIdx && shortPatternNoSecondsDigits[shortPatternNoSecondsDigits.length - 1] != "t") { - pattern = pattern.split(secondsWithSeparator)[0]; - } else { - pattern = shortPatternNoSecondsDigits; - } - } - return pattern; -} - -// wraps all substrings in the format in quotes, except for key words -// transform e.g. "HH h mm min ss s" into "HH 'h' mm 'min' ss 's'" -function wrapSubstrings (str: string) { - const words = str.split(/\s+/); - - for (let i = 0; i < words.length; i++) { - if (!words[i].includes(":") && !words[i].includes(".") && !keyWords.includes(words[i])) { - words[i] = `'${words[i]}'`; - } - } - - return words.join(" "); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts b/src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts deleted file mode 100644 index 251304dcc902b6..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts +++ /dev/null @@ -1,142 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/** - * This file is partially using code from FormatJS Intl.Segmenter implementation, reference: - * https://github.com/formatjs/formatjs/blob/58d6a7b398d776ca3d2726d72ae1573b65cc3bef/packages/intl-segmenter/src/segmenter.ts - * https://github.com/formatjs/formatjs/blob/58d6a7b398d776ca3d2726d72ae1573b65cc3bef/packages/intl-segmenter/src/segmentation-utils.ts - */ - -import { isSurrogate } from "./helpers"; - -type SegmentationRule = { - breaks: boolean - before?: RegExp - after?: RegExp -} - -type SegmentationRuleRaw = { - breaks: boolean - before?: string - after?: string -} - -type SegmentationTypeRaw = { - variables: Record - rules: Record -} - -let segmentationRules: Record; - -function replaceVariables (variables: Record, input: string): string { - const findVarRegex = /\$[A-Za-z0-9_]+/gm; - return input.replaceAll(findVarRegex, match => { - if (!(match in variables)) { - throw new Error(`No such variable ${match}`); - } - return variables[match]; - }); -} - -function generateRegexRule (rule: string, variables: Record, after: boolean): RegExp { - return new RegExp(`${after ? "^" : ""}${replaceVariables(variables, rule)}${after ? "" : "$"}`); -} - -function isSegmentationTypeRaw (obj: any): obj is SegmentationTypeRaw { - return obj.variables != null && obj.rules != null; -} - -export function setSegmentationRulesFromJson (json: string) { - if (!isSegmentationTypeRaw(json)) - throw new Error("Provided grapheme segmentation rules are not valid"); - segmentationRules = GraphemeSegmenter.prepareSegmentationRules(json); -} - -export class GraphemeSegmenter { - private readonly rules: Record; - private readonly ruleSortedKeys: string[]; - - public constructor () { - this.rules = segmentationRules; - this.ruleSortedKeys = Object.keys(this.rules).sort((a, b) => Number(a) - Number(b)); - } - - /** - * Returns the next grapheme in the given string starting from the specified index. - * @param str - The input string. - * @param startIndex - The starting index. - * @returns The next grapheme. - */ - public nextGrapheme (str: string, startIndex: number): string { - const breakIdx = this.nextGraphemeBreak(str, startIndex); - return str.substring(startIndex, breakIdx); - } - - /** - * Finds the index of the next grapheme break in a given string starting from a specified index. - * - * @param str - The input string. - * @param startIndex - The index to start searching from. - * @returns The index of the next grapheme break. - */ - public nextGraphemeBreak (str: string, startIndex: number): number { - if (startIndex < 0) - return 0; - - if (startIndex >= str.length - 1) - return str.length; - - let prev = String.fromCodePoint(str.codePointAt(startIndex)!); - for (let i = startIndex + 1; i < str.length; i++) { - // Don't break surrogate pairs - if (isSurrogate(str, i)) { - continue; - } - - const curr = String.fromCodePoint(str.codePointAt(i)!); - if (this.isGraphemeBreak(prev, curr)) - return i; - - prev = curr; - } - - return str.length; - } - - private isGraphemeBreak (previous: string, current: string): boolean { - for (const key of this.ruleSortedKeys) { - const { before, after, breaks } = this.rules[key]; - // match before and after rules - if (before && !before.test(previous)) { - continue; - } - if (after && !after.test(current)) { - continue; - } - - return breaks; - } - - // GB999: Any ÷ Any - return true; - } - - public static prepareSegmentationRules (segmentationRules: SegmentationTypeRaw): Record { - const preparedRules: Record = {}; - - for (const key of Object.keys(segmentationRules.rules)) { - const ruleValue = segmentationRules.rules[key]; - const preparedRule: SegmentationRule = { breaks: ruleValue.breaks, }; - - if ("before" in ruleValue && ruleValue.before) { - preparedRule.before = generateRegexRule(ruleValue.before, segmentationRules.variables, false); - } - if ("after" in ruleValue && ruleValue.after) { - preparedRule.after = generateRegexRule(ruleValue.after, segmentationRules.variables, true); - } - - preparedRules[key] = preparedRule; - } - return preparedRules; - } -} diff --git a/src/mono/browser/runtime/hybrid-globalization/helpers.ts b/src/mono/browser/runtime/hybrid-globalization/helpers.ts deleted file mode 100644 index 5bf28026404a9c..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/helpers.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -const SURROGATE_HIGHER_START = "\uD800"; -const SURROGATE_HIGHER_END = "\uDBFF"; -const SURROGATE_LOWER_START = "\uDC00"; -const SURROGATE_LOWER_END = "\uDFFF"; - -export const OUTER_SEPARATOR = "##"; -export const INNER_SEPARATOR = "||"; - -export function normalizeLocale (locale: string | null) { - if (!locale) - return undefined; - try { - locale = locale.toLocaleLowerCase(); - if (locale.includes("zh")) { - // browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-HANS" "zh-HANT", we are helping, otherwise - // it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided" - locale = locale.replace("chs", "HANS").replace("cht", "HANT"); - } - const canonicalLocales = (Intl as any).getCanonicalLocales(locale.replace("_", "-")); - return canonicalLocales.length > 0 ? canonicalLocales[0] : undefined; - } catch { - return undefined; - } -} - -export function isSurrogate (str: string, startIdx: number): boolean { - return SURROGATE_HIGHER_START <= str[startIdx] && - str[startIdx] <= SURROGATE_HIGHER_END && - startIdx + 1 < str.length && - SURROGATE_LOWER_START <= str[startIdx + 1] && - str[startIdx + 1] <= SURROGATE_LOWER_END; -} diff --git a/src/mono/browser/runtime/hybrid-globalization/locales.ts b/src/mono/browser/runtime/hybrid-globalization/locales.ts deleted file mode 100644 index 0dc4c8bcc67fce..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/locales.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { normalizeLocale } from "./helpers"; - -export function mono_wasm_get_first_day_of_week (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const canonicalLocale = normalizeLocale(cultureName); - const result = getFirstDayOfWeek(canonicalLocale); - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, -1); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_get_first_week_of_year (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const canonicalLocale = normalizeLocale(cultureName); - const result = getFirstWeekOfYear(canonicalLocale); - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, -1); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function getFirstDayOfWeek (locale: string) { - const weekInfo = getWeekInfo(locale); - if (weekInfo) { - // JS's Sunday == 7 while dotnet's Sunday == 0 - return weekInfo.firstDay == 7 ? 0 : weekInfo.firstDay; - } - // Firefox does not support it rn but we can make a temporary workaround for it, - // that should be removed when it starts being supported: - const saturdayLocales = ["en-AE", "en-SD", "fa-IR"]; - if (saturdayLocales.includes(locale)) { - return 6; - } - const sundayLanguages = ["th", "pt", "mr", "ml", "ko", "kn", "ja", "id", "hi", "he", "gu", "fil", "bn", "am", "ar", "te"]; - const sundayLocales = ["ta-SG", "ta-IN", "sw-KE", "ms-SG", "fr-CA", "es-MX", "en-US", "en-ZW", "en-ZA", "en-WS", "en-VI", "en-UM", "en-TT", "en-SG", "en-PR", "en-PK", "en-PH", "en-MT", "en-MO", "en-MH", "en-KE", "en-JM", "en-IN", "en-IL", "en-HK", "en-GU", "en-DM", "en-CA", "en-BZ", "en-BW", "en-BS", "en-AS", "en-AG", "zh-Hans-HK", "zh-SG", "zh-HK", "zh-TW"]; // "en-AU" is Monday in chrome, so firefox should be in line - const localeLang = locale.split("-")[0]; - if (sundayLanguages.includes(localeLang) || sundayLocales.includes(locale)) { - return 0; - } - return 1; -} - -function getFirstWeekOfYear (locale: string) { - const weekInfo = getWeekInfo(locale); - if (weekInfo) { - // enum CalendarWeekRule - // FirstDay = 0, // when minimalDays < 4 - // FirstFullWeek = 1, // when miminalDays == 7 - // FirstFourDayWeek = 2 // when miminalDays >= 4 - return weekInfo.minimalDays == 7 ? 1 : - weekInfo.minimalDays < 4 ? 0 : 2; - } - // Firefox does not support it rn but we can make a temporary workaround for it, - // that should be removed when it starts being supported: - const firstFourDayWeekLocales = ["pt-PT", "fr-CH", "fr-FR", "fr-BE", "es-ES", "en-SE", "en-NL", "en-JE", "en-IM", "en-IE", "en-GI", "en-GG", "en-GB", "en-FJ", "en-FI", "en-DK", "en-DE", "en-CH", "en-BE", "en-AT", "el-GR", "nl-BE", "nl-NL"]; - const firstFourDayWeekLanguages = ["sv", "sk", "ru", "pl", "no", "nb", "lt", "it", "hu", "fi", "et", "de", "da", "cs", "ca", "bg"]; - const localeLang = locale.split("-")[0]; - if (firstFourDayWeekLocales.includes(locale) || firstFourDayWeekLanguages.includes(localeLang)) { - return 2; - } - return 0; -} - -function getWeekInfo (locale: string) { - try { - // most tools have it implemented as property - return (new Intl.Locale(locale) as any).weekInfo; - } catch { - try { - // but a few use methods, which is the preferred way - return (new Intl.Locale(locale) as any).getWeekInfo(); - } catch { - return undefined; - } - } -} diff --git a/src/mono/browser/runtime/hybrid-globalization/module-exports.ts b/src/mono/browser/runtime/hybrid-globalization/module-exports.ts deleted file mode 100644 index f17bf90d4f2458..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/module-exports.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { GlobalizationHelpers, RuntimeHelpers } from "../types/internal"; -import { mono_wasm_get_calendar_info } from "./calendar"; -import { mono_wasm_change_case } from "./change-case"; -import { mono_wasm_compare_string, mono_wasm_starts_with, mono_wasm_ends_with, mono_wasm_index_of } from "./collations"; -import { mono_wasm_get_culture_info } from "./culture-info"; -import { setSegmentationRulesFromJson } from "./grapheme-segmenter"; -import { mono_wasm_get_first_day_of_week, mono_wasm_get_first_week_of_year } from "./locales"; - -export let globalizationHelpers: GlobalizationHelpers; -export let runtimeHelpers: RuntimeHelpers; - -export function initHybrid (gh: GlobalizationHelpers, rh: RuntimeHelpers) { - gh.mono_wasm_change_case = mono_wasm_change_case; - gh.mono_wasm_compare_string = mono_wasm_compare_string; - gh.mono_wasm_starts_with = mono_wasm_starts_with; - gh.mono_wasm_ends_with = mono_wasm_ends_with; - gh.mono_wasm_index_of = mono_wasm_index_of; - gh.mono_wasm_get_calendar_info = mono_wasm_get_calendar_info; - gh.mono_wasm_get_culture_info = mono_wasm_get_culture_info; - gh.mono_wasm_get_first_day_of_week = mono_wasm_get_first_day_of_week; - gh.mono_wasm_get_first_week_of_year = mono_wasm_get_first_week_of_year; - gh.setSegmentationRulesFromJson = setSegmentationRulesFromJson; - globalizationHelpers = gh; - runtimeHelpers = rh; -} - diff --git a/src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json b/src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json deleted file mode 100644 index f99c632f843178..00000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "rules": { - "3": { - "after": "$LF", - "before": "$CR", - "breaks": false - }, - "4": { - "before": "($Control|$CR|$LF)", - "breaks": true - }, - "5": { - "after": "($Control|$CR|$LF)", - "breaks": true - }, - "6": { - "after": "($L|$V|$LV|$LVT)", - "before": "$L", - "breaks": false - }, - "7": { - "after": "($V|$T)", - "before": "($LV|$V)", - "breaks": false - }, - "8": { - "after": "$T", - "before": "($LVT|$T)", - "breaks": false - }, - "9": { - "after": "($Extend|$ZWJ)", - "breaks": false - }, - "11": { - "after": "$ExtPict", - "before": "$ExtPict$Extend*$ZWJ", - "breaks": false - }, - "12": { - "after": "$RI", - "before": "^($RI$RI)*$RI", - "breaks": false - }, - "13": { - "after": "$RI", - "before": "[^\\uDDE6-\\uDDFF]($RI$RI)*$RI", - "breaks": false - }, - "9.1": { - "after": "$SpacingMark", - "breaks": false - }, - "9.2": { - "before": "$Prepend", - "breaks": false - }, - "9.3": { - "after": "$LinkingConsonant", - "before": "$LinkingConsonant$ExtCccZwj*$Virama$ExtCccZwj*", - "breaks": false - } - }, - "variables": { - "$CR": "\\r", - "$Control": "(?:[\\0-\\t\\x0B\\f\\x0E-\\x1F\\x7F-\\x9F\\xAD\\u061C\\u180E\\u200B\\u200E\\u200F\\u2028-\\u202E\\u2060-\\u206F\\uFEFF\\uFFF0-\\uFFFB]|\\uD80D[\\uDC30-\\uDC3F]|\\uD82F[\\uDCA0-\\uDCA3]|\\uD834[\\uDD73-\\uDD7A]|\\uDB40[\\uDC00-\\uDC1F\\uDC80-\\uDCFF\\uDDF0-\\uDFFF]|[\\uDB41-\\uDB43][\\uDC00-\\uDFFF])", - "$ExtCccZwj": "(?:[\\u0300-\\u034E\\u0350-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07EB-\\u07F3\\u07FD\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u0898-\\u089F\\u08CA-\\u08E1\\u08E3-\\u08FF\\u093C\\u094D\\u0951-\\u0954\\u09BC\\u09CD\\u09FE\\u0A3C\\u0A4D\\u0ABC\\u0ACD\\u0B3C\\u0B4D\\u0BCD\\u0C3C\\u0C4D\\u0C55\\u0C56\\u0CBC\\u0CCD\\u0D3B\\u0D3C\\u0D4D\\u0DCA\\u0E38-\\u0E3A\\u0E48-\\u0E4B\\u0EB8-\\u0EBA\\u0EC8-\\u0ECB\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71\\u0F72\\u0F74\\u0F7A-\\u0F7D\\u0F80\\u0F82-\\u0F84\\u0F86\\u0F87\\u0FC6\\u1037\\u1039\\u103A\\u108D\\u135D-\\u135F\\u1714\\u17D2\\u17DD\\u18A9\\u1939-\\u193B\\u1A17\\u1A18\\u1A60\\u1A75-\\u1A7C\\u1A7F\\u1AB0-\\u1ABD\\u1ABF-\\u1ACE\\u1B34\\u1B6B-\\u1B73\\u1BAB\\u1BE6\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DFF\\u200D\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA806\\uA82C\\uA8C4\\uA8E0-\\uA8F1\\uA92B-\\uA92D\\uA9B3\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAF6\\uABED\\uFB1E\\uFE20-\\uFE2F]|\\uD800[\\uDDFD\\uDEE0\\uDF76-\\uDF7A]|\\uD802[\\uDE0D\\uDE0F\\uDE38-\\uDE3A\\uDE3F\\uDEE5\\uDEE6]|\\uD803[\\uDD24-\\uDD27\\uDEAB\\uDEAC\\uDEFD-\\uDEFF\\uDF46-\\uDF50\\uDF82-\\uDF85]|\\uD804[\\uDC46\\uDC70\\uDC7F\\uDCB9\\uDCBA\\uDD00-\\uDD02\\uDD33\\uDD34\\uDD73\\uDDCA\\uDE36\\uDEE9\\uDEEA\\uDF3B\\uDF3C\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC42\\uDC46\\uDC5E\\uDCC2\\uDCC3\\uDDBF\\uDDC0\\uDE3F\\uDEB7\\uDF2B]|\\uD806[\\uDC39\\uDC3A\\uDD3E\\uDD43\\uDDE0\\uDE34\\uDE47\\uDE99]|\\uD807[\\uDC3F\\uDD42\\uDD44\\uDD45\\uDD97\\uDF42]|\\uD81A[\\uDEF0-\\uDEF4\\uDF30-\\uDF36]|\\uD82F\\uDC9E|\\uD834[\\uDD65\\uDD67-\\uDD69\\uDD6E-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD838[\\uDC00-\\uDC06\\uDC08-\\uDC18\\uDC1B-\\uDC21\\uDC23\\uDC24\\uDC26-\\uDC2A\\uDC8F\\uDD30-\\uDD36\\uDEAE\\uDEEC-\\uDEEF]|\\uD839[\\uDCEC-\\uDCEF]|\\uD83A[\\uDCD0-\\uDCD6\\uDD44-\\uDD4A])", - "$ExtPict": "(?:[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u2388\\u23CF\\u23E9-\\u23F3\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB-\\u25FE\\u2600-\\u2605\\u2607-\\u2612\\u2614-\\u2685\\u2690-\\u2705\\u2708-\\u2712\\u2714\\u2716\\u271D\\u2721\\u2728\\u2733\\u2734\\u2744\\u2747\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2763-\\u2767\\u2795-\\u2797\\u27A1\\u27B0\\u27BF\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B50\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC00-\\uDCFF\\uDD0D-\\uDD0F\\uDD2F\\uDD6C-\\uDD71\\uDD7E\\uDD7F\\uDD8E\\uDD91-\\uDD9A\\uDDAD-\\uDDE5\\uDE01-\\uDE0F\\uDE1A\\uDE2F\\uDE32-\\uDE3A\\uDE3C-\\uDE3F\\uDE49-\\uDFFA]|\\uD83D[\\uDC00-\\uDD3D\\uDD46-\\uDE4F\\uDE80-\\uDEFF\\uDF74-\\uDF7F\\uDFD5-\\uDFFF]|\\uD83E[\\uDC0C-\\uDC0F\\uDC48-\\uDC4F\\uDC5A-\\uDC5F\\uDC88-\\uDC8F\\uDCAE-\\uDCFF\\uDD0C-\\uDD3A\\uDD3C-\\uDD45\\uDD47-\\uDEFF]|\\uD83F[\\uDC00-\\uDFFD])", - "$Extend": "(?:[\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u07FD\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u0898-\\u089F\\u08CA-\\u08E1\\u08E3-\\u0902\\u093A\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0957\\u0962\\u0963\\u0981\\u09BC\\u09BE\\u09C1-\\u09C4\\u09CD\\u09D7\\u09E2\\u09E3\\u09FE\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0AFA-\\u0AFF\\u0B01\\u0B3C\\u0B3E\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B55-\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE\\u0BC0\\u0BCD\\u0BD7\\u0C00\\u0C04\\u0C3C\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81\\u0CBC\\u0CBF\\u0CC2\\u0CC6\\u0CCC\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D00\\u0D01\\u0D3B\\u0D3C\\u0D3E\\u0D41-\\u0D44\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D81\\u0DCA\\u0DCF\\u0DD2-\\u0DD4\\u0DD6\\u0DDF\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EBC\\u0EC8-\\u0ECE\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732\\u1733\\u1752\\u1753\\u1772\\u1773\\u17B4\\u17B5\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u180F\\u1885\\u1886\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A1B\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1AB0-\\u1ACE\\u1B00-\\u1B03\\u1B34-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1BAB-\\u1BAD\\u1BE6\\u1BE8\\u1BE9\\u1BED\\u1BEF-\\u1BF1\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DFF\\u200C\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA82C\\uA8C4\\uA8C5\\uA8E0-\\uA8F1\\uA8FF\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uA9BD\\uA9E5\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAA7C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEC\\uAAED\\uAAF6\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F\\uFF9E\\uFF9F]|\\uD800[\\uDDFD\\uDEE0\\uDF76-\\uDF7A]|\\uD802[\\uDE01-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE0F\\uDE38-\\uDE3A\\uDE3F\\uDEE5\\uDEE6]|\\uD803[\\uDD24-\\uDD27\\uDEAB\\uDEAC\\uDEFD-\\uDEFF\\uDF46-\\uDF50\\uDF82-\\uDF85]|\\uD804[\\uDC01\\uDC38-\\uDC46\\uDC70\\uDC73\\uDC74\\uDC7F-\\uDC81\\uDCB3-\\uDCB6\\uDCB9\\uDCBA\\uDCC2\\uDD00-\\uDD02\\uDD27-\\uDD2B\\uDD2D-\\uDD34\\uDD73\\uDD80\\uDD81\\uDDB6-\\uDDBE\\uDDC9-\\uDDCC\\uDDCF\\uDE2F-\\uDE31\\uDE34\\uDE36\\uDE37\\uDE3E\\uDE41\\uDEDF\\uDEE3-\\uDEEA\\uDF00\\uDF01\\uDF3B\\uDF3C\\uDF3E\\uDF40\\uDF57\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC38-\\uDC3F\\uDC42-\\uDC44\\uDC46\\uDC5E\\uDCB0\\uDCB3-\\uDCB8\\uDCBA\\uDCBD\\uDCBF\\uDCC0\\uDCC2\\uDCC3\\uDDAF\\uDDB2-\\uDDB5\\uDDBC\\uDDBD\\uDDBF\\uDDC0\\uDDDC\\uDDDD\\uDE33-\\uDE3A\\uDE3D\\uDE3F\\uDE40\\uDEAB\\uDEAD\\uDEB0-\\uDEB5\\uDEB7\\uDF1D-\\uDF1F\\uDF22-\\uDF25\\uDF27-\\uDF2B]|\\uD806[\\uDC2F-\\uDC37\\uDC39\\uDC3A\\uDD30\\uDD3B\\uDD3C\\uDD3E\\uDD43\\uDDD4-\\uDDD7\\uDDDA\\uDDDB\\uDDE0\\uDE01-\\uDE0A\\uDE33-\\uDE38\\uDE3B-\\uDE3E\\uDE47\\uDE51-\\uDE56\\uDE59-\\uDE5B\\uDE8A-\\uDE96\\uDE98\\uDE99]|\\uD807[\\uDC30-\\uDC36\\uDC38-\\uDC3D\\uDC3F\\uDC92-\\uDCA7\\uDCAA-\\uDCB0\\uDCB2\\uDCB3\\uDCB5\\uDCB6\\uDD31-\\uDD36\\uDD3A\\uDD3C\\uDD3D\\uDD3F-\\uDD45\\uDD47\\uDD90\\uDD91\\uDD95\\uDD97\\uDEF3\\uDEF4\\uDF00\\uDF01\\uDF36-\\uDF3A\\uDF40\\uDF42]|\\uD80D[\\uDC40\\uDC47-\\uDC55]|\\uD81A[\\uDEF0-\\uDEF4\\uDF30-\\uDF36]|\\uD81B[\\uDF4F\\uDF8F-\\uDF92\\uDFE4]|\\uD82F[\\uDC9D\\uDC9E]|\\uD833[\\uDF00-\\uDF2D\\uDF30-\\uDF46]|\\uD834[\\uDD65\\uDD67-\\uDD69\\uDD6E-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD836[\\uDE00-\\uDE36\\uDE3B-\\uDE6C\\uDE75\\uDE84\\uDE9B-\\uDE9F\\uDEA1-\\uDEAF]|\\uD838[\\uDC00-\\uDC06\\uDC08-\\uDC18\\uDC1B-\\uDC21\\uDC23\\uDC24\\uDC26-\\uDC2A\\uDC8F\\uDD30-\\uDD36\\uDEAE\\uDEEC-\\uDEEF]|\\uD839[\\uDCEC-\\uDCEF]|\\uD83A[\\uDCD0-\\uDCD6\\uDD44-\\uDD4A]|\\uD83C[\\uDFFB-\\uDFFF]|\\uDB40[\\uDC20-\\uDC7F\\uDD00-\\uDDEF])", - "$L": "[\\u1100-\\u115F\\uA960-\\uA97C]", - "$LF": "\\n", - "$LV": "[\\uAC00\\uAC1C\\uAC38\\uAC54\\uAC70\\uAC8C\\uACA8\\uACC4\\uACE0\\uACFC\\uAD18\\uAD34\\uAD50\\uAD6C\\uAD88\\uADA4\\uADC0\\uADDC\\uADF8\\uAE14\\uAE30\\uAE4C\\uAE68\\uAE84\\uAEA0\\uAEBC\\uAED8\\uAEF4\\uAF10\\uAF2C\\uAF48\\uAF64\\uAF80\\uAF9C\\uAFB8\\uAFD4\\uAFF0\\uB00C\\uB028\\uB044\\uB060\\uB07C\\uB098\\uB0B4\\uB0D0\\uB0EC\\uB108\\uB124\\uB140\\uB15C\\uB178\\uB194\\uB1B0\\uB1CC\\uB1E8\\uB204\\uB220\\uB23C\\uB258\\uB274\\uB290\\uB2AC\\uB2C8\\uB2E4\\uB300\\uB31C\\uB338\\uB354\\uB370\\uB38C\\uB3A8\\uB3C4\\uB3E0\\uB3FC\\uB418\\uB434\\uB450\\uB46C\\uB488\\uB4A4\\uB4C0\\uB4DC\\uB4F8\\uB514\\uB530\\uB54C\\uB568\\uB584\\uB5A0\\uB5BC\\uB5D8\\uB5F4\\uB610\\uB62C\\uB648\\uB664\\uB680\\uB69C\\uB6B8\\uB6D4\\uB6F0\\uB70C\\uB728\\uB744\\uB760\\uB77C\\uB798\\uB7B4\\uB7D0\\uB7EC\\uB808\\uB824\\uB840\\uB85C\\uB878\\uB894\\uB8B0\\uB8CC\\uB8E8\\uB904\\uB920\\uB93C\\uB958\\uB974\\uB990\\uB9AC\\uB9C8\\uB9E4\\uBA00\\uBA1C\\uBA38\\uBA54\\uBA70\\uBA8C\\uBAA8\\uBAC4\\uBAE0\\uBAFC\\uBB18\\uBB34\\uBB50\\uBB6C\\uBB88\\uBBA4\\uBBC0\\uBBDC\\uBBF8\\uBC14\\uBC30\\uBC4C\\uBC68\\uBC84\\uBCA0\\uBCBC\\uBCD8\\uBCF4\\uBD10\\uBD2C\\uBD48\\uBD64\\uBD80\\uBD9C\\uBDB8\\uBDD4\\uBDF0\\uBE0C\\uBE28\\uBE44\\uBE60\\uBE7C\\uBE98\\uBEB4\\uBED0\\uBEEC\\uBF08\\uBF24\\uBF40\\uBF5C\\uBF78\\uBF94\\uBFB0\\uBFCC\\uBFE8\\uC004\\uC020\\uC03C\\uC058\\uC074\\uC090\\uC0AC\\uC0C8\\uC0E4\\uC100\\uC11C\\uC138\\uC154\\uC170\\uC18C\\uC1A8\\uC1C4\\uC1E0\\uC1FC\\uC218\\uC234\\uC250\\uC26C\\uC288\\uC2A4\\uC2C0\\uC2DC\\uC2F8\\uC314\\uC330\\uC34C\\uC368\\uC384\\uC3A0\\uC3BC\\uC3D8\\uC3F4\\uC410\\uC42C\\uC448\\uC464\\uC480\\uC49C\\uC4B8\\uC4D4\\uC4F0\\uC50C\\uC528\\uC544\\uC560\\uC57C\\uC598\\uC5B4\\uC5D0\\uC5EC\\uC608\\uC624\\uC640\\uC65C\\uC678\\uC694\\uC6B0\\uC6CC\\uC6E8\\uC704\\uC720\\uC73C\\uC758\\uC774\\uC790\\uC7AC\\uC7C8\\uC7E4\\uC800\\uC81C\\uC838\\uC854\\uC870\\uC88C\\uC8A8\\uC8C4\\uC8E0\\uC8FC\\uC918\\uC934\\uC950\\uC96C\\uC988\\uC9A4\\uC9C0\\uC9DC\\uC9F8\\uCA14\\uCA30\\uCA4C\\uCA68\\uCA84\\uCAA0\\uCABC\\uCAD8\\uCAF4\\uCB10\\uCB2C\\uCB48\\uCB64\\uCB80\\uCB9C\\uCBB8\\uCBD4\\uCBF0\\uCC0C\\uCC28\\uCC44\\uCC60\\uCC7C\\uCC98\\uCCB4\\uCCD0\\uCCEC\\uCD08\\uCD24\\uCD40\\uCD5C\\uCD78\\uCD94\\uCDB0\\uCDCC\\uCDE8\\uCE04\\uCE20\\uCE3C\\uCE58\\uCE74\\uCE90\\uCEAC\\uCEC8\\uCEE4\\uCF00\\uCF1C\\uCF38\\uCF54\\uCF70\\uCF8C\\uCFA8\\uCFC4\\uCFE0\\uCFFC\\uD018\\uD034\\uD050\\uD06C\\uD088\\uD0A4\\uD0C0\\uD0DC\\uD0F8\\uD114\\uD130\\uD14C\\uD168\\uD184\\uD1A0\\uD1BC\\uD1D8\\uD1F4\\uD210\\uD22C\\uD248\\uD264\\uD280\\uD29C\\uD2B8\\uD2D4\\uD2F0\\uD30C\\uD328\\uD344\\uD360\\uD37C\\uD398\\uD3B4\\uD3D0\\uD3EC\\uD408\\uD424\\uD440\\uD45C\\uD478\\uD494\\uD4B0\\uD4CC\\uD4E8\\uD504\\uD520\\uD53C\\uD558\\uD574\\uD590\\uD5AC\\uD5C8\\uD5E4\\uD600\\uD61C\\uD638\\uD654\\uD670\\uD68C\\uD6A8\\uD6C4\\uD6E0\\uD6FC\\uD718\\uD734\\uD750\\uD76C\\uD788]", - "$LVT": "[\\uAC01-\\uAC1B\\uAC1D-\\uAC37\\uAC39-\\uAC53\\uAC55-\\uAC6F\\uAC71-\\uAC8B\\uAC8D-\\uACA7\\uACA9-\\uACC3\\uACC5-\\uACDF\\uACE1-\\uACFB\\uACFD-\\uAD17\\uAD19-\\uAD33\\uAD35-\\uAD4F\\uAD51-\\uAD6B\\uAD6D-\\uAD87\\uAD89-\\uADA3\\uADA5-\\uADBF\\uADC1-\\uADDB\\uADDD-\\uADF7\\uADF9-\\uAE13\\uAE15-\\uAE2F\\uAE31-\\uAE4B\\uAE4D-\\uAE67\\uAE69-\\uAE83\\uAE85-\\uAE9F\\uAEA1-\\uAEBB\\uAEBD-\\uAED7\\uAED9-\\uAEF3\\uAEF5-\\uAF0F\\uAF11-\\uAF2B\\uAF2D-\\uAF47\\uAF49-\\uAF63\\uAF65-\\uAF7F\\uAF81-\\uAF9B\\uAF9D-\\uAFB7\\uAFB9-\\uAFD3\\uAFD5-\\uAFEF\\uAFF1-\\uB00B\\uB00D-\\uB027\\uB029-\\uB043\\uB045-\\uB05F\\uB061-\\uB07B\\uB07D-\\uB097\\uB099-\\uB0B3\\uB0B5-\\uB0CF\\uB0D1-\\uB0EB\\uB0ED-\\uB107\\uB109-\\uB123\\uB125-\\uB13F\\uB141-\\uB15B\\uB15D-\\uB177\\uB179-\\uB193\\uB195-\\uB1AF\\uB1B1-\\uB1CB\\uB1CD-\\uB1E7\\uB1E9-\\uB203\\uB205-\\uB21F\\uB221-\\uB23B\\uB23D-\\uB257\\uB259-\\uB273\\uB275-\\uB28F\\uB291-\\uB2AB\\uB2AD-\\uB2C7\\uB2C9-\\uB2E3\\uB2E5-\\uB2FF\\uB301-\\uB31B\\uB31D-\\uB337\\uB339-\\uB353\\uB355-\\uB36F\\uB371-\\uB38B\\uB38D-\\uB3A7\\uB3A9-\\uB3C3\\uB3C5-\\uB3DF\\uB3E1-\\uB3FB\\uB3FD-\\uB417\\uB419-\\uB433\\uB435-\\uB44F\\uB451-\\uB46B\\uB46D-\\uB487\\uB489-\\uB4A3\\uB4A5-\\uB4BF\\uB4C1-\\uB4DB\\uB4DD-\\uB4F7\\uB4F9-\\uB513\\uB515-\\uB52F\\uB531-\\uB54B\\uB54D-\\uB567\\uB569-\\uB583\\uB585-\\uB59F\\uB5A1-\\uB5BB\\uB5BD-\\uB5D7\\uB5D9-\\uB5F3\\uB5F5-\\uB60F\\uB611-\\uB62B\\uB62D-\\uB647\\uB649-\\uB663\\uB665-\\uB67F\\uB681-\\uB69B\\uB69D-\\uB6B7\\uB6B9-\\uB6D3\\uB6D5-\\uB6EF\\uB6F1-\\uB70B\\uB70D-\\uB727\\uB729-\\uB743\\uB745-\\uB75F\\uB761-\\uB77B\\uB77D-\\uB797\\uB799-\\uB7B3\\uB7B5-\\uB7CF\\uB7D1-\\uB7EB\\uB7ED-\\uB807\\uB809-\\uB823\\uB825-\\uB83F\\uB841-\\uB85B\\uB85D-\\uB877\\uB879-\\uB893\\uB895-\\uB8AF\\uB8B1-\\uB8CB\\uB8CD-\\uB8E7\\uB8E9-\\uB903\\uB905-\\uB91F\\uB921-\\uB93B\\uB93D-\\uB957\\uB959-\\uB973\\uB975-\\uB98F\\uB991-\\uB9AB\\uB9AD-\\uB9C7\\uB9C9-\\uB9E3\\uB9E5-\\uB9FF\\uBA01-\\uBA1B\\uBA1D-\\uBA37\\uBA39-\\uBA53\\uBA55-\\uBA6F\\uBA71-\\uBA8B\\uBA8D-\\uBAA7\\uBAA9-\\uBAC3\\uBAC5-\\uBADF\\uBAE1-\\uBAFB\\uBAFD-\\uBB17\\uBB19-\\uBB33\\uBB35-\\uBB4F\\uBB51-\\uBB6B\\uBB6D-\\uBB87\\uBB89-\\uBBA3\\uBBA5-\\uBBBF\\uBBC1-\\uBBDB\\uBBDD-\\uBBF7\\uBBF9-\\uBC13\\uBC15-\\uBC2F\\uBC31-\\uBC4B\\uBC4D-\\uBC67\\uBC69-\\uBC83\\uBC85-\\uBC9F\\uBCA1-\\uBCBB\\uBCBD-\\uBCD7\\uBCD9-\\uBCF3\\uBCF5-\\uBD0F\\uBD11-\\uBD2B\\uBD2D-\\uBD47\\uBD49-\\uBD63\\uBD65-\\uBD7F\\uBD81-\\uBD9B\\uBD9D-\\uBDB7\\uBDB9-\\uBDD3\\uBDD5-\\uBDEF\\uBDF1-\\uBE0B\\uBE0D-\\uBE27\\uBE29-\\uBE43\\uBE45-\\uBE5F\\uBE61-\\uBE7B\\uBE7D-\\uBE97\\uBE99-\\uBEB3\\uBEB5-\\uBECF\\uBED1-\\uBEEB\\uBEED-\\uBF07\\uBF09-\\uBF23\\uBF25-\\uBF3F\\uBF41-\\uBF5B\\uBF5D-\\uBF77\\uBF79-\\uBF93\\uBF95-\\uBFAF\\uBFB1-\\uBFCB\\uBFCD-\\uBFE7\\uBFE9-\\uC003\\uC005-\\uC01F\\uC021-\\uC03B\\uC03D-\\uC057\\uC059-\\uC073\\uC075-\\uC08F\\uC091-\\uC0AB\\uC0AD-\\uC0C7\\uC0C9-\\uC0E3\\uC0E5-\\uC0FF\\uC101-\\uC11B\\uC11D-\\uC137\\uC139-\\uC153\\uC155-\\uC16F\\uC171-\\uC18B\\uC18D-\\uC1A7\\uC1A9-\\uC1C3\\uC1C5-\\uC1DF\\uC1E1-\\uC1FB\\uC1FD-\\uC217\\uC219-\\uC233\\uC235-\\uC24F\\uC251-\\uC26B\\uC26D-\\uC287\\uC289-\\uC2A3\\uC2A5-\\uC2BF\\uC2C1-\\uC2DB\\uC2DD-\\uC2F7\\uC2F9-\\uC313\\uC315-\\uC32F\\uC331-\\uC34B\\uC34D-\\uC367\\uC369-\\uC383\\uC385-\\uC39F\\uC3A1-\\uC3BB\\uC3BD-\\uC3D7\\uC3D9-\\uC3F3\\uC3F5-\\uC40F\\uC411-\\uC42B\\uC42D-\\uC447\\uC449-\\uC463\\uC465-\\uC47F\\uC481-\\uC49B\\uC49D-\\uC4B7\\uC4B9-\\uC4D3\\uC4D5-\\uC4EF\\uC4F1-\\uC50B\\uC50D-\\uC527\\uC529-\\uC543\\uC545-\\uC55F\\uC561-\\uC57B\\uC57D-\\uC597\\uC599-\\uC5B3\\uC5B5-\\uC5CF\\uC5D1-\\uC5EB\\uC5ED-\\uC607\\uC609-\\uC623\\uC625-\\uC63F\\uC641-\\uC65B\\uC65D-\\uC677\\uC679-\\uC693\\uC695-\\uC6AF\\uC6B1-\\uC6CB\\uC6CD-\\uC6E7\\uC6E9-\\uC703\\uC705-\\uC71F\\uC721-\\uC73B\\uC73D-\\uC757\\uC759-\\uC773\\uC775-\\uC78F\\uC791-\\uC7AB\\uC7AD-\\uC7C7\\uC7C9-\\uC7E3\\uC7E5-\\uC7FF\\uC801-\\uC81B\\uC81D-\\uC837\\uC839-\\uC853\\uC855-\\uC86F\\uC871-\\uC88B\\uC88D-\\uC8A7\\uC8A9-\\uC8C3\\uC8C5-\\uC8DF\\uC8E1-\\uC8FB\\uC8FD-\\uC917\\uC919-\\uC933\\uC935-\\uC94F\\uC951-\\uC96B\\uC96D-\\uC987\\uC989-\\uC9A3\\uC9A5-\\uC9BF\\uC9C1-\\uC9DB\\uC9DD-\\uC9F7\\uC9F9-\\uCA13\\uCA15-\\uCA2F\\uCA31-\\uCA4B\\uCA4D-\\uCA67\\uCA69-\\uCA83\\uCA85-\\uCA9F\\uCAA1-\\uCABB\\uCABD-\\uCAD7\\uCAD9-\\uCAF3\\uCAF5-\\uCB0F\\uCB11-\\uCB2B\\uCB2D-\\uCB47\\uCB49-\\uCB63\\uCB65-\\uCB7F\\uCB81-\\uCB9B\\uCB9D-\\uCBB7\\uCBB9-\\uCBD3\\uCBD5-\\uCBEF\\uCBF1-\\uCC0B\\uCC0D-\\uCC27\\uCC29-\\uCC43\\uCC45-\\uCC5F\\uCC61-\\uCC7B\\uCC7D-\\uCC97\\uCC99-\\uCCB3\\uCCB5-\\uCCCF\\uCCD1-\\uCCEB\\uCCED-\\uCD07\\uCD09-\\uCD23\\uCD25-\\uCD3F\\uCD41-\\uCD5B\\uCD5D-\\uCD77\\uCD79-\\uCD93\\uCD95-\\uCDAF\\uCDB1-\\uCDCB\\uCDCD-\\uCDE7\\uCDE9-\\uCE03\\uCE05-\\uCE1F\\uCE21-\\uCE3B\\uCE3D-\\uCE57\\uCE59-\\uCE73\\uCE75-\\uCE8F\\uCE91-\\uCEAB\\uCEAD-\\uCEC7\\uCEC9-\\uCEE3\\uCEE5-\\uCEFF\\uCF01-\\uCF1B\\uCF1D-\\uCF37\\uCF39-\\uCF53\\uCF55-\\uCF6F\\uCF71-\\uCF8B\\uCF8D-\\uCFA7\\uCFA9-\\uCFC3\\uCFC5-\\uCFDF\\uCFE1-\\uCFFB\\uCFFD-\\uD017\\uD019-\\uD033\\uD035-\\uD04F\\uD051-\\uD06B\\uD06D-\\uD087\\uD089-\\uD0A3\\uD0A5-\\uD0BF\\uD0C1-\\uD0DB\\uD0DD-\\uD0F7\\uD0F9-\\uD113\\uD115-\\uD12F\\uD131-\\uD14B\\uD14D-\\uD167\\uD169-\\uD183\\uD185-\\uD19F\\uD1A1-\\uD1BB\\uD1BD-\\uD1D7\\uD1D9-\\uD1F3\\uD1F5-\\uD20F\\uD211-\\uD22B\\uD22D-\\uD247\\uD249-\\uD263\\uD265-\\uD27F\\uD281-\\uD29B\\uD29D-\\uD2B7\\uD2B9-\\uD2D3\\uD2D5-\\uD2EF\\uD2F1-\\uD30B\\uD30D-\\uD327\\uD329-\\uD343\\uD345-\\uD35F\\uD361-\\uD37B\\uD37D-\\uD397\\uD399-\\uD3B3\\uD3B5-\\uD3CF\\uD3D1-\\uD3EB\\uD3ED-\\uD407\\uD409-\\uD423\\uD425-\\uD43F\\uD441-\\uD45B\\uD45D-\\uD477\\uD479-\\uD493\\uD495-\\uD4AF\\uD4B1-\\uD4CB\\uD4CD-\\uD4E7\\uD4E9-\\uD503\\uD505-\\uD51F\\uD521-\\uD53B\\uD53D-\\uD557\\uD559-\\uD573\\uD575-\\uD58F\\uD591-\\uD5AB\\uD5AD-\\uD5C7\\uD5C9-\\uD5E3\\uD5E5-\\uD5FF\\uD601-\\uD61B\\uD61D-\\uD637\\uD639-\\uD653\\uD655-\\uD66F\\uD671-\\uD68B\\uD68D-\\uD6A7\\uD6A9-\\uD6C3\\uD6C5-\\uD6DF\\uD6E1-\\uD6FB\\uD6FD-\\uD717\\uD719-\\uD733\\uD735-\\uD74F\\uD751-\\uD76B\\uD76D-\\uD787\\uD789-\\uD7A3]", - "$LinkingConsonant": "[\\u0915-\\u0939\\u0958-\\u095F\\u0978-\\u097F\\u0995-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09DC\\u09DD\\u09DF\\u09F0\\u09F1\\u0A95-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0AF9\\u0B15-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B5C\\u0B5D\\u0B5F\\u0B71\\u0C15-\\u0C28\\u0C2A-\\u0C39\\u0C58-\\u0C5A\\u0D15-\\u0D3A]", - "$Prepend": "(?:[\\u0600-\\u0605\\u06DD\\u070F\\u0890\\u0891\\u08E2\\u0D4E]|\\uD804[\\uDCBD\\uDCCD\\uDDC2\\uDDC3]|\\uD806[\\uDD3F\\uDD41\\uDE3A\\uDE84-\\uDE89]|\\uD807[\\uDD46\\uDF02])", - "$RI": "(?:\\uD83C[\\uDDE6-\\uDDFF])", - "$SpacingMark": "(?:[\\u0903\\u093B\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u094F\\u0982\\u0983\\u09BF\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0\\u0CC1\\u0CC3\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CF3\\u0D02\\u0D03\\u0D3F\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D82\\u0D83\\u0DD0\\u0DD1\\u0DD8-\\u0DDE\\u0DF2\\u0DF3\\u0E33\\u0EB3\\u0F3E\\u0F3F\\u0F7F\\u1031\\u103B\\u103C\\u1056\\u1057\\u1084\\u1715\\u1734\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u1A19\\u1A1A\\u1A55\\u1A57\\u1A6D-\\u1A72\\u1B04\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1BE7\\u1BEA-\\u1BEC\\u1BEE\\u1BF2\\u1BF3\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF7\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BE-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAAEB\\uAAEE\\uAAEF\\uAAF5\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]|\\uD804[\\uDC00\\uDC02\\uDC82\\uDCB0-\\uDCB2\\uDCB7\\uDCB8\\uDD2C\\uDD45\\uDD46\\uDD82\\uDDB3-\\uDDB5\\uDDBF\\uDDC0\\uDDCE\\uDE2C-\\uDE2E\\uDE32\\uDE33\\uDE35\\uDEE0-\\uDEE2\\uDF02\\uDF03\\uDF3F\\uDF41-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF62\\uDF63]|\\uD805[\\uDC35-\\uDC37\\uDC40\\uDC41\\uDC45\\uDCB1\\uDCB2\\uDCB9\\uDCBB\\uDCBC\\uDCBE\\uDCC1\\uDDB0\\uDDB1\\uDDB8-\\uDDBB\\uDDBE\\uDE30-\\uDE32\\uDE3B\\uDE3C\\uDE3E\\uDEAC\\uDEAE\\uDEAF\\uDEB6\\uDF26]|\\uD806[\\uDC2C-\\uDC2E\\uDC38\\uDD31-\\uDD35\\uDD37\\uDD38\\uDD3D\\uDD40\\uDD42\\uDDD1-\\uDDD3\\uDDDC-\\uDDDF\\uDDE4\\uDE39\\uDE57\\uDE58\\uDE97]|\\uD807[\\uDC2F\\uDC3E\\uDCA9\\uDCB1\\uDCB4\\uDD8A-\\uDD8E\\uDD93\\uDD94\\uDD96\\uDEF5\\uDEF6\\uDF03\\uDF34\\uDF35\\uDF3E\\uDF3F\\uDF41]|\\uD81B[\\uDF51-\\uDF87\\uDFF0\\uDFF1]|\\uD834[\\uDD66\\uDD6D])", - "$T": "[\\u11A8-\\u11FF\\uD7CB-\\uD7FB]", - "$V": "[\\u1160-\\u11A7\\uD7B0-\\uD7C6]", - "$Virama": "[\\u094D\\u09CD\\u0ACD\\u0B4D\\u0C4D\\u0D4D]", - "$ZWJ": "\\u200D" - } -} diff --git a/src/mono/browser/runtime/loader/assets.ts b/src/mono/browser/runtime/loader/assets.ts index 50bc98ef0217fb..e749fb42afb783 100644 --- a/src/mono/browser/runtime/loader/assets.ts +++ b/src/mono/browser/runtime/loader/assets.ts @@ -4,7 +4,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads"; import { PThreadPtrNull, type AssetEntryInternal, type PThreadWorker, type PromiseAndController } from "../types/internal"; -import { GlobalizationMode, type AssetBehaviors, type AssetEntry, type LoadingResource, type ResourceList, type SingleAssetBehaviors as SingleAssetBehaviors, type WebAssemblyBootResourceType } from "../types"; +import { type AssetBehaviors, type AssetEntry, type LoadingResource, type ResourceList, type SingleAssetBehaviors as SingleAssetBehaviors, type WebAssemblyBootResourceType } from "../types"; import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, ENVIRONMENT_IS_WORKER, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; import { createPromiseController } from "./promise-controller"; import { mono_log_debug, mono_log_warn } from "./logging"; @@ -29,7 +29,6 @@ const jsRuntimeModulesAssetTypes: { [k: string]: boolean } = { "js-module-threads": true, - "js-module-globalization": true, "js-module-runtime": true, "js-module-dotnet": true, "js-module-native": true, @@ -72,8 +71,7 @@ const skipBufferByAssetTypes: { [k: string]: boolean } = { "dotnetwasm": true, - "symbols": true, - "segmentation-rules": true, + "symbols": true }; // these assets are instantiated differently than the main flow @@ -82,8 +80,7 @@ const skipInstantiateByAssetTypes: { } = { ...jsModulesAssetTypes, "dotnetwasm": true, - "symbols": true, - "segmentation-rules": true, + "symbols": true }; // load again for each worker @@ -91,7 +88,6 @@ const loadIntoWorker: { [k: string]: boolean } = { "symbols": true, - "segmentation-rules": true, }; export function shouldLoadIcuAsset (asset: AssetEntryInternal): boolean { @@ -223,9 +219,6 @@ export async function mono_download_assets (): Promise { if (asset.behavior === "symbols") { await runtimeHelpers.instantiate_symbols_asset(asset); cleanupAsset(asset); - } else if (asset.behavior === "segmentation-rules") { - await runtimeHelpers.instantiate_segmentation_rules_asset(asset); - cleanupAsset(asset); } if (skipBufferByAssetTypes[asset.behavior]) { @@ -313,9 +306,6 @@ export function prepareAssets () { if (WasmEnableThreads) { convert_single_asset(modulesAssets, resources.jsModuleWorker, "js-module-threads"); } - if (config.globalizationMode == GlobalizationMode.Hybrid) { - convert_single_asset(modulesAssets, resources.jsModuleGlobalization, "js-module-globalization"); - } const addAsset = (asset: AssetEntryInternal, isCore: boolean) => { if (resources.fingerprinting && (asset.behavior == "assembly" || asset.behavior == "pdb" || asset.behavior == "resource")) { @@ -421,12 +411,6 @@ export function prepareAssets () { behavior: "icu", loadRemote: true }); - } else if (name.startsWith("segmentation-rules") && name.endsWith(".json")) { - assetsToLoad.push({ - name, - hash: resources.icu[name], - behavior: "segmentation-rules", - }); } } } diff --git a/src/mono/browser/runtime/loader/config.ts b/src/mono/browser/runtime/loader/config.ts index 24afa653772faa..3165672e6257e6 100644 --- a/src/mono/browser/runtime/loader/config.ts +++ b/src/mono/browser/runtime/loader/config.ts @@ -71,9 +71,6 @@ function deep_merge_resources (target: ResourceGroups, source: ResourceGroups): if (providedResources.jsModuleNative !== undefined) { providedResources.jsModuleNative = { ...(target.jsModuleNative || {}), ...(providedResources.jsModuleNative || {}) }; } - if (providedResources.jsModuleGlobalization !== undefined) { - providedResources.jsModuleGlobalization = { ...(target.jsModuleGlobalization || {}), ...(providedResources.jsModuleGlobalization || {}) }; - } if (providedResources.jsModuleRuntime !== undefined) { providedResources.jsModuleRuntime = { ...(target.jsModuleRuntime || {}), ...(providedResources.jsModuleRuntime || {}) }; } @@ -124,7 +121,6 @@ export function normalizeConfig () { config.resources = config.resources || { assembly: {}, jsModuleNative: {}, - jsModuleGlobalization: {}, jsModuleWorker: {}, jsModuleRuntime: {}, wasmNative: {}, @@ -165,9 +161,6 @@ export function normalizeConfig () { case "js-module-threads": toMerge.jsModuleWorker = resource; break; - case "js-module-globalization": - toMerge.jsModuleGlobalization = resource; - break; case "js-module-runtime": toMerge.jsModuleRuntime = resource; break; diff --git a/src/mono/browser/runtime/loader/globals.ts b/src/mono/browser/runtime/loader/globals.ts index 91e0a89f2c0f9e..5ef69d0e2e8ced 100644 --- a/src/mono/browser/runtime/loader/globals.ts +++ b/src/mono/browser/runtime/loader/globals.ts @@ -8,7 +8,7 @@ import { exceptions, simd } from "wasm-feature-detect"; import gitHash from "consts:gitHash"; -import type { DotnetModuleInternal, GlobalObjects, GlobalizationHelpers, LoaderHelpers, MonoConfigInternal, PThreadWorker, RuntimeHelpers } from "../types/internal"; +import type { DotnetModuleInternal, GlobalObjects, LoaderHelpers, MonoConfigInternal, PThreadWorker, RuntimeHelpers } from "../types/internal"; import type { MonoConfig, RuntimeAPI } from "../types"; import { assert_runtime_running, installUnhandledErrorHandler, is_exited, is_runtime_running, mono_exit } from "./exit"; import { assertIsControllablePromise, createPromiseController, getPromiseController } from "./promise-controller"; @@ -32,7 +32,6 @@ export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_W export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE; export let runtimeHelpers: RuntimeHelpers = {} as any; -export let globalizationHelpers: GlobalizationHelpers = {} as any; export let loaderHelpers: LoaderHelpers = {} as any; export let exportedRuntimeAPI: RuntimeAPI = {} as any; export let INTERNAL: any = {}; @@ -49,7 +48,6 @@ export const globalObjectsRoot: GlobalObjects = { module: emscriptenModule, loaderHelpers, runtimeHelpers, - globalizationHelpers, api: exportedRuntimeAPI, } as any; @@ -63,7 +61,6 @@ export function setLoaderGlobals ( } _loaderModuleLoaded = true; runtimeHelpers = globalObjects.runtimeHelpers; - globalizationHelpers = globalObjects.globalizationHelpers; loaderHelpers = globalObjects.loaderHelpers; exportedRuntimeAPI = globalObjects.api; INTERNAL = globalObjects.internal; diff --git a/src/mono/browser/runtime/loader/icu.ts b/src/mono/browser/runtime/loader/icu.ts index 20b6a4578f0a3d..1e90674a67dcce 100644 --- a/src/mono/browser/runtime/loader/icu.ts +++ b/src/mono/browser/runtime/loader/icu.ts @@ -26,11 +26,8 @@ export function init_globalization () { } const invariantEnv = "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"; - const hybridEnv = "DOTNET_SYSTEM_GLOBALIZATION_HYBRID"; const env_variables = loaderHelpers.config.environmentVariables!; - if (env_variables[hybridEnv] === undefined && loaderHelpers.config.globalizationMode === GlobalizationMode.Hybrid) { - env_variables[hybridEnv] = "1"; - } else if (env_variables[invariantEnv] === undefined && invariantMode) { + if (env_variables[invariantEnv] === undefined && invariantMode) { env_variables[invariantEnv] = "1"; } if (env_variables["TZ"] === undefined) { @@ -70,8 +67,6 @@ export function getIcuResourceName (config: MonoConfig): string | null { if (icuFiles.length >= 1) { return icuFiles[0]; } - } else if (config.globalizationMode === GlobalizationMode.Hybrid) { - icuFile = "icudt_hybrid.dat"; } else if (!culture || config.globalizationMode === GlobalizationMode.All) { icuFile = "icudt.dat"; } else if (config.globalizationMode === GlobalizationMode.Sharded) { diff --git a/src/mono/browser/runtime/loader/run.ts b/src/mono/browser/runtime/loader/run.ts index 6afe902c868c59..dc507d794d3767 100644 --- a/src/mono/browser/runtime/loader/run.ts +++ b/src/mono/browser/runtime/loader/run.ts @@ -3,8 +3,8 @@ import BuildConfiguration from "consts:configuration"; -import { type MonoConfig, type DotnetHostBuilder, type DotnetModuleConfig, type RuntimeAPI, type LoadBootResourceCallback, GlobalizationMode } from "../types"; -import type { EmscriptenModuleInternal, RuntimeModuleExportsInternal, NativeModuleExportsInternal, HybridGlobalizationModuleExportsInternal, } from "../types/internal"; +import { type MonoConfig, type DotnetHostBuilder, type DotnetModuleConfig, type RuntimeAPI, type LoadBootResourceCallback } from "../types"; +import type { EmscriptenModuleInternal, RuntimeModuleExportsInternal, NativeModuleExportsInternal } from "../types/internal"; import { ENVIRONMENT_IS_WEB, ENVIRONMENT_IS_WORKER, emscriptenModule, exportedRuntimeAPI, globalObjectsRoot, monoConfig, mono_assert } from "./globals"; import { deep_merge_config, deep_merge_module, mono_wasm_load_config } from "./config"; @@ -12,7 +12,7 @@ import { installUnhandledErrorHandler, mono_exit, registerEmscriptenExitHandlers import { setup_proxy_console, mono_log_info, mono_log_debug } from "./logging"; import { mono_download_assets, preloadWorkers, prepareAssets, prepareAssetsWorker, resolve_single_asset_path, streamingCompileWasm } from "./assets"; import { detect_features_and_polyfill } from "./polyfills"; -import { runtimeHelpers, loaderHelpers, globalizationHelpers } from "./globals"; +import { runtimeHelpers, loaderHelpers } from "./globals"; import { init_globalization } from "./icu"; import { setupPreloadChannelToMainThread } from "./worker"; import { importLibraryInitializers, invokeLibraryInitializers } from "./libraryInitializers"; @@ -459,30 +459,11 @@ function importModules () { return [jsModuleRuntimePromise, jsModuleNativePromise]; } -async function getHybridModuleExports () : Promise { - let jsModuleHybridGlobalizationPromise: Promise | undefined = undefined; - // todo: move it for after runtime startup - const jsModuleHybridGlobalization = resolve_single_asset_path("js-module-globalization"); - if (typeof jsModuleHybridGlobalization.moduleExports === "object") { - jsModuleHybridGlobalizationPromise = jsModuleHybridGlobalization.moduleExports; - } else { - mono_log_debug(`Attempting to import '${jsModuleHybridGlobalization.resolvedUrl}' for ${jsModuleHybridGlobalization.name}`); - jsModuleHybridGlobalizationPromise = import(/*! webpackIgnore: true */jsModuleHybridGlobalization.resolvedUrl!); - } - const hybridModule = await jsModuleHybridGlobalizationPromise; - return hybridModule as any; -} - async function initializeModules (es6Modules: [RuntimeModuleExportsInternal, NativeModuleExportsInternal]) { const { initializeExports, initializeReplacements, configureRuntimeStartup, configureEmscriptenStartup, configureWorkerStartup, setRuntimeGlobals, passEmscriptenInternals } = es6Modules[0]; const { default: emscriptenFactory } = es6Modules[1]; setRuntimeGlobals(globalObjectsRoot); initializeExports(globalObjectsRoot); - if (loaderHelpers.config.globalizationMode === GlobalizationMode.Hybrid) { - const hybridModule = await getHybridModuleExports(); - const { initHybrid } = hybridModule; - initHybrid(globalizationHelpers, runtimeHelpers); - } await configureRuntimeStartup(emscriptenModule); loaderHelpers.runtimeModuleLoaded.promise_control.resolve(); diff --git a/src/mono/browser/runtime/rollup.config.js b/src/mono/browser/runtime/rollup.config.js index 31d3ed7e6e3456..9b976e54cd98c9 100644 --- a/src/mono/browser/runtime/rollup.config.js +++ b/src/mono/browser/runtime/rollup.config.js @@ -225,20 +225,6 @@ const typesConfig = { plugins: [dts()], onwarn: onwarn }; -const hybridGlobalizationConfig = { - input: "./hybrid-globalization/module-exports.ts", - output: [ - { - format: "es", - file: nativeBinDir + "/dotnet.globalization.js", - banner, - sourcemap: true, - sourcemapPathTransform, - } - ], - plugins: [...outputCodePlugins], - onwarn: onwarn -}; let diagnosticMockTypesConfig = undefined; @@ -294,7 +280,6 @@ const allConfigs = [ runtimeConfig, wasmImportsConfig, typesConfig, - hybridGlobalizationConfig, ] .concat(workerConfigs) .concat(diagnosticMockTypesConfig ? [diagnosticMockTypesConfig] : []); diff --git a/src/mono/browser/runtime/types/index.ts b/src/mono/browser/runtime/types/index.ts index c3658624dff198..eb6c12a1b3e2e5 100644 --- a/src/mono/browser/runtime/types/index.ts +++ b/src/mono/browser/runtime/types/index.ts @@ -326,10 +326,6 @@ export type SingleAssetBehaviors = * The javascript module for emscripten. */ | "js-module-native" - /** - * The javascript module for hybrid globalization. - */ - | "js-module-globalization" /** * Typically blazor.boot.json */ @@ -338,10 +334,6 @@ export type SingleAssetBehaviors = * The debugging symbols */ | "symbols" - /** - * Load segmentation rules file for Hybrid Globalization. - */ - | "segmentation-rules"; export type AssetBehaviors = SingleAssetBehaviors | /** @@ -389,11 +381,7 @@ export const enum GlobalizationMode { /** * Use user defined icu file. */ - Custom = "custom", - /** - * Operate in hybrid globalization mode with small ICU files, using native platform functions. - */ - Hybrid = "hybrid" + Custom = "custom" } export type DotnetModuleConfig = { diff --git a/src/mono/browser/runtime/types/internal.ts b/src/mono/browser/runtime/types/internal.ts index 2b2792056a8d10..54f11256806273 100644 --- a/src/mono/browser/runtime/types/internal.ts +++ b/src/mono/browser/runtime/types/internal.ts @@ -239,7 +239,6 @@ export type RuntimeHelpers = { stringify_as_error_with_stack?: (error: any) => string, instantiate_asset: (asset: AssetEntry, url: string, bytes: Uint8Array) => void, instantiate_symbols_asset: (pendingAsset: AssetEntryInternal) => Promise, - instantiate_segmentation_rules_asset: (pendingAsset: AssetEntryInternal) => Promise, jiterpreter_dump_stats?: (concise?: boolean) => void, forceDisposeProxies: (disposeMethods: boolean, verbose: boolean) => void, dumpThreads: () => void, @@ -253,19 +252,6 @@ export type RuntimeHelpers = { setU16_local: (heap: Uint16Array, ptr: number, value: number) => void, setI32: (offset: MemOffset, value: number) => void, } -export type GlobalizationHelpers = { - - mono_wasm_change_case: (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number) => VoidPtr; - mono_wasm_compare_string: (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_starts_with: (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_ends_with: (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_index_of: (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_get_calendar_info: (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr) => VoidPtr; - mono_wasm_get_culture_info: (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr) => VoidPtr; - mono_wasm_get_first_day_of_week: (culture: number, cultureLength: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_get_first_week_of_year: (culture: number, cultureLength: number, resultPtr: Int32Ptr) => VoidPtr; - setSegmentationRulesFromJson: (json: string) => void; -} export type AOTProfilerOptions = { writeAt?: string, // should be in the format ::, default: 'WebAssembly.Runtime::StopProfile' @@ -317,7 +303,6 @@ export type GlobalObjects = { module: DotnetModuleInternal, loaderHelpers: LoaderHelpers, runtimeHelpers: RuntimeHelpers, - globalizationHelpers: GlobalizationHelpers, api: RuntimeAPI, }; export type EmscriptenReplacements = { @@ -517,10 +502,6 @@ export type NativeModuleExportsInternal = { default: (unificator: Function) => Promise } -export type HybridGlobalizationModuleExportsInternal = { - initHybrid: (gh: GlobalizationHelpers, rh: RuntimeHelpers) => void; -} - export type WeakRefInternal = WeakRef & { dispose?: () => void } diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 12a3e2121a8ab8..1596acac199074 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -145,31 +145,23 @@ Copyright (c) .NET Foundation. All rights reserved. - - - <_RuntimePackDir>$(MicrosoftNetCoreAppRuntimePackDir) <_RuntimePackDir Condition="'$(_RuntimePackDir)' == ''">%(ResolvedRuntimePack.PackageDirectory) <_RuntimePackNativeDir>$([MSBuild]::NormalizeDirectory($(_RuntimePackDir), 'runtimes', 'browser-wasm', 'native')) - <_LoadCustomIcuData Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' != 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' != 'true' AND '$(BlazorIcuDataFileName)' != ''">true + <_LoadCustomIcuData Condition="'$(InvariantGlobalization)' != 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' != 'true' AND '$(BlazorIcuDataFileName)' != ''">true <_LoadCustomIcuData Condition="'$(_LoadCustomIcuData)' == ''">false <_BlazorIcuDataFileName Condition="'$(_LoadCustomIcuData)' == 'true' AND Exists('$(BlazorIcuDataFileName)')">$(BlazorIcuDataFileName) <_BlazorIcuDataFileName Condition="'$(_LoadCustomIcuData)' == 'true' AND !Exists('$(BlazorIcuDataFileName)') AND !$([System.IO.Path]::IsPathRooted($(BlazorIcuDataFileName)))">$(_RuntimePackNativeDir)$(BlazorIcuDataFileName) - <_IsHybridGlobalization Condition="'$(InvariantGlobalization)' != 'true' AND '$(_LoadCustomIcuData)' != 'true'">$(HybridGlobalization) - <_IsHybridGlobalization Condition="'$(_IsHybridGlobalization)' == ''">false - <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData) + <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData) <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(_BlazorWebAssemblyLoadAllGlobalizationData)' == ''">false - - - @@ -245,7 +237,6 @@ Copyright (c) .NET Foundation. All rights reserved. ProjectSatelliteAssemblies="@(IntermediateSatelliteAssembliesWithTargetPath)" TimeZoneSupport="$(_BlazorEnableTimeZoneSupport)" InvariantGlobalization="$(_WasmInvariantGlobalization)" - HybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)" OutputPath="$(OutputPath)" @@ -377,7 +368,6 @@ Copyright (c) .NET Foundation. All rights reserved. LazyLoadedAssemblies="@(BlazorWebAssemblyLazyLoad)" InvariantGlobalization="$(InvariantGlobalization)" LoadCustomIcuData="$(_LoadCustomIcuData)" - IsHybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)" Jiterpreter="$(_BlazorWebAssemblyJiterpreter)" @@ -484,7 +474,6 @@ Copyright (c) .NET Foundation. All rights reserved. PublishPath="$(PublishDir)" WasmAotAssets="@(WasmNativeAsset)" InvariantGlobalization="$(_WasmInvariantGlobalization)" - HybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" CopySymbols="$(CopyOutputSymbolsToPublishDirectory)" ExistingAssets="@(_WasmPublishPrefilteredAssets)" @@ -668,7 +657,6 @@ Copyright (c) .NET Foundation. All rights reserved. LazyLoadedAssemblies="@(BlazorWebAssemblyLazyLoad)" InvariantGlobalization="$(InvariantGlobalization)" LoadCustomIcuData="$(_LoadCustomIcuData)" - IsHybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)" Jiterpreter="$(_BlazorWebAssemblyJiterpreter)" diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props index 3743cddf79083d..c429f998d9befa 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props @@ -1,7 +1,6 @@ false - false false false true diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets index ec001114f27451..5c25ac9731da82 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets @@ -17,7 +17,6 @@ - diff --git a/src/mono/sample/wasm/Directory.Build.targets b/src/mono/sample/wasm/Directory.Build.targets index 8982f866eefe27..751980f96bc004 100644 --- a/src/mono/sample/wasm/Directory.Build.targets +++ b/src/mono/sample/wasm/Directory.Build.targets @@ -31,7 +31,6 @@ Outputs=" bin/$(Configuration)/AppBundle/dotnet.native.wasm; bin/$(Configuration)/AppBundle/dotnet.native.js; - bin/$(Configuration)/AppBundle/dotnet.globalization.js; bin/$(Configuration)/AppBundle/$(_WasmMainJSFileName); "> @@ -43,7 +42,6 @@ - diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs b/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs index 250dbe7dc5b6bf..b1687109bb4aef 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs @@ -10,5 +10,4 @@ public enum GlobalizationMode Invariant, // no icu FullIcu, // full icu data: icudt.dat is loaded Custom, // user set WasmIcuDataFileName/BlazorIcuDataFileName value and we are loading that file - Hybrid // reduced icu, missing data is provided by platform-native functions (web api for wasm) }; diff --git a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs index 7bf3ce67c2c9b5..56cd08e08eef7f 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs @@ -341,7 +341,6 @@ private string[] GetFilesMatchingNameConsideringFingerprinting(string filePath, Path.Combine(paths.BinFrameworkDir, "dotnet.native.wasm"), Path.Combine(paths.BinFrameworkDir, "dotnet.native.js"), - Path.Combine(paths.BinFrameworkDir, "dotnet.globalization.js"), }; if (isAOT) @@ -365,7 +364,6 @@ private string[] GetFilesMatchingNameConsideringFingerprinting(string filePath, dict["dotnet.js.map"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.js.map"), true); dict["dotnet.runtime.js"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.runtime.js"), true); dict["dotnet.runtime.js.map"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.runtime.js.map"), true); - dict["dotnet.globalization.js"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.globalization.js"), true); if (IsFingerprintingEnabled) { @@ -435,10 +433,6 @@ public void AssertIcuAssets(AssertBundleOptions assertOptions, BootJsonData boot case GlobalizationMode.FullIcu: expected.Add("icudt.dat"); break; - case GlobalizationMode.Hybrid: - expected.Add("icudt_hybrid.dat"); - expected.Add("segmentation-rules.json"); - break; case GlobalizationMode.Custom: if (string.IsNullOrEmpty(assertOptions.BuildOptions.CustomIcuFile)) throw new ArgumentException("WasmBuildTest is invalid, value for Custom globalization mode is required when GlobalizationMode=Custom."); @@ -457,8 +451,6 @@ public void AssertIcuAssets(AssertBundleOptions assertOptions, BootJsonData boot } IEnumerable actual = Directory.EnumerateFiles(assertOptions.BinFrameworkDir, "icudt*dat"); - if (assertOptions.BuildOptions.GlobalizationMode == GlobalizationMode.Hybrid) - actual = actual.Union(Directory.EnumerateFiles(assertOptions.BinFrameworkDir, "segmentation-rules*json")); if (IsFingerprintingEnabled) { diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs index c04d0bf50c2f65..89b99ca922fe10 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs @@ -31,7 +31,6 @@ protected override IReadOnlyDictionary GetAllKnownDotnetFilesToFin { "dotnet.js.map", false }, { "dotnet.native.js", true }, { "dotnet.native.js.symbols", false }, - { "dotnet.globalization.js", true }, { "dotnet.native.wasm", true }, { "dotnet.native.worker.mjs", true }, { "dotnet.runtime.js", true }, @@ -51,10 +50,6 @@ protected override IReadOnlySet GetDotNetFilesExpectedSet(AssertBundleOp { res.Add("dotnet.native.worker.mjs"); } - if (assertOptions.BuildOptions.GlobalizationMode is GlobalizationMode.Hybrid) - { - res.Add("dotnet.globalization.js"); - } if (!assertOptions.BuildOptions.IsPublish) { @@ -131,10 +126,6 @@ private void AssertBundle(AssertBundleOptions assertOptions) { nativeFilesToCheck.Add("dotnet.native.worker.mjs"); } - if (assertOptions.BuildOptions.GlobalizationMode == GlobalizationMode.Hybrid) - { - nativeFilesToCheck.Add("dotnet.globalization.js"); - } foreach (string nativeFilename in nativeFilesToCheck) { @@ -171,7 +162,7 @@ public void AssertWasmSdkBundle(Configuration config, MSBuildOptions buildOption } AssertBundle(config, buildOptions, isUsingWorkloads, isNativeBuild); } - + public BuildPaths GetBuildPaths(Configuration configuration, bool forPublish) { Assert.NotNull(ProjectDir); @@ -179,12 +170,12 @@ public BuildPaths GetBuildPaths(Configuration configuration, bool forPublish) string objDir = Path.Combine(ProjectDir, "obj", configStr, _defaultTargetFramework); string binDir = Path.Combine(ProjectDir, "bin", configStr, _defaultTargetFramework); string binFrameworkDir = GetBinFrameworkDir(configuration, forPublish, _defaultTargetFramework); - + string objWasmDir = Path.Combine(objDir, "wasm", forPublish ? "for-publish" : "for-build"); // for build: we should take from runtime pack? return new BuildPaths(objWasmDir, objDir, binDir, binFrameworkDir); } - + public override string GetBinFrameworkDir(Configuration config, bool forPublish, string framework, string? projectDir = null) { EnsureProjectDirIsSet(); @@ -194,4 +185,4 @@ public override string GetBinFrameworkDir(Configuration config, bool forPublish, return Path.Combine(basePath, BundleDirName, "_framework"); } -} \ No newline at end of file +} diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets index c073f2e5593007..be718671187a1c 100644 --- a/src/mono/wasm/build/WasmApp.Common.targets +++ b/src/mono/wasm/build/WasmApp.Common.targets @@ -26,7 +26,6 @@ - $(AOTProfilePath) - profile data file to be used for profile-guided optimization - $(InvariantGlobalization) - Whether to disable ICU. Defaults to false. - $(InvariantTimezone) - Whether to disable Timezone database. Defaults to false. - - $(HybridGlobalization) - Whether to enable reduced ICU + native platform functions. Defaults to false and can be set only for InvariantGlobalization=false, WasmIncludeFullIcuData=false and empty WasmIcuDataFileName. - $(WasmResolveAssembliesBeforeBuild) - Resolve the assembly dependencies. Defaults to false - $(WasmAssemblySearchPaths) - used for resolving assembly dependencies diff --git a/src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs b/src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs deleted file mode 100644 index d318530fb26ffa..00000000000000 --- a/src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Globalization; - -void WriteTestOutput(string output) => Console.WriteLine($"TestOutput -> {output}"); - -try -{ - CompareInfo compareInfo = new CultureInfo("es-ES").CompareInfo; - int shouldBeEqual = compareInfo.Compare("A\u0300", "\u00C0", CompareOptions.None); - if (shouldBeEqual != 0) - { - return 1; - } - int shouldThrow = compareInfo.Compare("A\u0300", "\u00C0", CompareOptions.IgnoreNonSpace); - WriteTestOutput($"Did not throw as expected but returned {shouldThrow} as a result. Using CompareOptions.IgnoreNonSpace option alone should be unavailable in HybridGlobalization mode."); -} -catch (PlatformNotSupportedException pnse) -{ - WriteTestOutput($"HybridGlobalization works, thrown exception as expected: {pnse}."); - return 42; -} -catch (Exception ex) -{ - WriteTestOutput($"HybridGlobalization failed, unexpected exception was thrown: {ex}."); - return 2; -} -return 3; diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs index b7bdbd752edb81..ecbc3e9c6b631b 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs @@ -36,7 +36,6 @@ public static bool ShouldFilterCandidate( ITaskItem candidate, bool timezoneSupport, bool invariantGlobalization, - bool hybridGlobalization, bool loadFullICUData, bool copySymbols, string customIcuCandidateFilename, @@ -63,8 +62,6 @@ public static bool ShouldFilterCandidate( ".blat" when !timezoneSupport => "timezone support is not enabled.", ".dat" when invariantGlobalization && fileName.StartsWith("icudt") => "invariant globalization is enabled", ".dat" when loadFullICUData && fileName != "icudt" => "full ICU data is enabled", - ".dat" when hybridGlobalization && fileName != "icudt_hybrid" => "hybrid globalization is enabled", - ".json" when !hybridGlobalization && fileName == "segmentation-rules" => "segmentation-rules.json file is only used when hybrid globalization is enabled", ".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file either from absolute path or from runtime pack path will be used", ".dat" when IsDefaultIcuMode() && !(icuShardsFromRuntimePack.Any(f => f == fileName)) => "automatic icu shard selection, based on application culture, is enabled", ".json" when fromMonoPackage && (fileName == "wasm-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor", @@ -83,7 +80,6 @@ public static bool ShouldFilterCandidate( bool IsDefaultIcuMode() => !invariantGlobalization && !loadFullICUData && - !hybridGlobalization && string.IsNullOrEmpty(customIcuCandidateFilename); } @@ -121,8 +117,6 @@ public static string GetCandidateRelativePath(ITaskItem candidate, bool fingerpr ("dotnet.runtime", ".js") => string.Concat(fileName, requiredFingerprint, extension), ("dotnet.native", ".js") => string.Concat(fileName, requiredFingerprint, extension), ("dotnet.native.worker", ".mjs") => string.Concat(fileName, requiredFingerprint, extension), - ("dotnet.globalization", ".js") => string.Concat(fileName, requiredFingerprint, extension), - ("segmentation-rules", ".json") => string.Concat(fileName, requiredFingerprint, extension), _ => string.Concat(fileName, extension) }; } diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs index b7559ddce65084..7c6c0836f4a2ce 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs @@ -103,8 +103,6 @@ static void AddDictionary(StringBuilder sb, Dictionary? res) return bootConfig.resources.wasmSymbols ??= new(); else if (resourceName.StartsWith("icudt", StringComparison.OrdinalIgnoreCase)) return bootConfig.resources.icu ??= new(); - else if (resourceName.Equals("segmentation-rules.json", StringComparison.OrdinalIgnoreCase)) - return bootConfig.resources.icu ??= new(); else Log.LogError($"The resource '{resourceName}' is not recognized as any native asset"); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs index 8df0f567148cb3..32e09c9826c109 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs @@ -252,11 +252,6 @@ public enum GlobalizationMode : int /// Load custom icu file provided by the developer. /// Custom = 3, - - /// - /// Use the reduced icudt_hybrid.dat file - /// - Hybrid = 4, } [DataContract] diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs index cb070606f49c0d..a9e9b91cb4e9e1 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs @@ -40,9 +40,6 @@ public class ComputeWasmBuildAssets : Task [Required] public bool InvariantGlobalization { get; set; } - [Required] - public bool HybridGlobalization { get; set; } - [Required] public bool LoadFullICUData { get; set; } @@ -91,7 +88,7 @@ public override bool Execute() for (int i = 0; i < Candidates.Length; i++) { var candidate = Candidates[i]; - if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) + if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) { Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason); filesToRemove.Add(candidate); @@ -235,7 +232,6 @@ private static void ApplyUniqueMetadataProperties(ITaskItem candidate) case ".js" when filename.StartsWith("dotnet"): case ".mjs" when filename.StartsWith("dotnet"): case ".dat" when filename.StartsWith("icudt"): - case ".json" when filename.StartsWith("segmentation-rules"): candidate.SetMetadata("AssetTraitName", "WasmResource"); candidate.SetMetadata("AssetTraitValue", "native"); break; diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs index 3ea146e92e6edc..ff555a8f8cba35 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs @@ -43,9 +43,6 @@ public class ComputeWasmPublishAssets : Task [Required] public bool InvariantGlobalization { get; set; } - [Required] - public bool HybridGlobalization { get; set; } - [Required] public bool LoadFullICUData { get; set; } @@ -663,7 +660,7 @@ private void GroupResolvedFilesToPublish( foreach (var candidate in resolvedFilesToPublish) { #pragma warning disable CA1864 // Prefer the 'IDictionary.TryAdd(TKey, TValue)' method. Dictionary.TryAdd() not available in .Net framework. - if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) + if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) { Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason); if (!resolvedFilesToPublishToRemove.ContainsKey(candidate.ItemSpec)) diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs index eaaf55c20ae939..4453684d1b098a 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs @@ -50,8 +50,6 @@ public class GenerateWasmBootJson : Task public bool LoadFullICUData { get; set; } - public bool IsHybridGlobalization { get; set; } - public bool LoadCustomIcuData { get; set; } public string InvariantGlobalization { get; set; } @@ -449,8 +447,6 @@ private GlobalizationMode GetGlobalizationMode() { if (string.Equals(InvariantGlobalization, "true", StringComparison.OrdinalIgnoreCase)) return GlobalizationMode.Invariant; - else if (IsHybridGlobalization) - return GlobalizationMode.Hybrid; else if (LoadFullICUData) return GlobalizationMode.All; else if (LoadCustomIcuData) diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 2bd56348e1a7db..2befd468f50d6d 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -84,10 +84,6 @@ private GlobalizationMode GetGlobalizationMode() if (!string.IsNullOrEmpty(WasmIcuDataFileName)) return GlobalizationMode.Custom; - // Hybrid mode - if (HybridGlobalization) - return GlobalizationMode.Hybrid; - // If user requested to include full ICU data, use it if (WasmIncludeFullIcuData) return GlobalizationMode.All; @@ -173,9 +169,6 @@ protected override bool ExecuteInternal() if (!IncludeThreadsWorker && name == "dotnet.native.worker.mjs") continue; - if (!HybridGlobalization && name == "dotnet.globalization.js") - continue; - if (name == "dotnet.runtime.js.map" || name == "dotnet.js.map") { Log.LogMessage(MessageImportance.Low, $"Skipping {item.ItemSpec} from boot config"); diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs index 97bae1eaf37314..4b2271d7ae4a3f 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs @@ -39,7 +39,6 @@ public abstract class WasmAppBuilderBaseTask : Task public string[] IcuDataFileNames { get; set; } = Array.Empty(); public ITaskItem[] SatelliteAssemblies { get; set; } = Array.Empty(); - public bool HybridGlobalization { get; set; } public bool InvariantGlobalization { get; set; } public ITaskItem[] FilesToIncludeInFileSystem { get; set; } = Array.Empty(); public ITaskItem[] ExtraFilesToDeploy { get; set; } = Array.Empty(); From 6d6f2bd36c7d5e134177383958b02522b770bd04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 17 Dec 2024 15:34:09 +0100 Subject: [PATCH 6/7] Fix base type marking for DAM annotated classes (#110655) Fixes #104740, also implements #110563 for ILC. The annotation on DAM annotated classes gets triggered by calling GetType on a location typed as something DAM annotated (or deriving/implementing from it). The marking is done in layers so that warning suppressions can be properly applied. The bug was that we didn't walk down the hierarchy and assumed someone else will do it. Nobody did. I'm adding a new node type to do the marking. Previously, we only used one node for tracking. The node got dropped into the dependency graph when we saw GetType being called and it ensured the proper marking for that one type (not the bases). We also added conditional dependencies into MethodTables so that `Derived` can depend on this node of the `Base`. This ensured that if GetType was called on Base, we'd treat it same as GetType on Derived. This was resulting in marking too much and too little (we'd mark right away when we saw GetType call, irrespective of the MethodTable existence, and we wouldn't walk down to Base if the GetType was called on Derived. The fix is to use two node types. One simply tracks "GetType was called on something". It doesn't bring any other dependencies with it. We only use it to condition other nodes. The other node represents "the dependencies from the annotations". The way this works is: * We see GetType called on Base, so we add ObjectGetTypeCalledNode for Base. * We generate MethodTable for Derived, which adds a conditional dependency on ObjectGetTypeCalledNode of Derived if ObjectGetTypeCalledNode of Base is in the graph. (This ensures "walking up the hierarchy".) * MethodTable of Derived also adds a conditional dependency on ObjectGetTypeFlowDependenciesNode of Derived if ObjectGetTypeCalledNode of Derived is part of the graph. This will do the actual marking but only if the MethodTable and GetType call was seen. * ObjectGetTypeFlowDependenciesNode also "walks down the hierarchy" and makes sure ObjectGetTypeFlowDependenciesNode of all the bases and interfaces are present in the graph. This happens to also address #110563. Because of that, I had to update tests since ILC started trimming more stuff without seeing the type as constructed. --- .../Compiler/Dataflow/HandleCallAction.cs | 2 +- .../Dataflow/ReflectionMethodBodyScanner.cs | 19 +++ .../DependencyAnalysis/NodeFactory.cs | 11 ++ .../ObjectGetTypeCalledNode.cs | 40 ++++++ .../ObjectGetTypeFlowDependenciesNode.cs | 28 ++-- .../Compiler/UsageBasedMetadataManager.cs | 24 +++- .../ILCompiler.Compiler.csproj | 1 + .../SmokeTests/TrimmingBehaviors/Dataflow.cs | 5 +- .../DataFlow/ObjectGetTypeDataflow.cs | 44 +++++- .../Generics/InstantiatedGenericEquality.cs | 4 +- .../Reflection/ObjectGetType.cs | 130 +++++++++++++++++- .../TypeHierarchyReflectionWarnings.cs | 34 +++-- .../Reflection/TypeHierarchySuppressions.cs | 1 + .../RequiresCapability/RequiresOnClass.cs | 10 +- 14 files changed, 313 insertions(+), 40 deletions(-) create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeCalledNode.cs diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs index 9ca8b98e9e1353..d1a8db0c1b999b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs @@ -455,7 +455,7 @@ private partial bool TryHandleIntrinsic ( if (annotation != default) { - _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ObjectGetTypeFlowDependencies(closestMetadataType), "GetType called on this type"); + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ObjectGetTypeCalled(closestMetadataType), "GetType called on this type"); } // Return a value which is "unknown type" with annotation. For now we'll use the return value node diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index ce3493118082a9..4738e0755bf08b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -130,6 +130,25 @@ public static DependencyList ProcessTypeGetTypeDataflow(NodeFactory factory, Flo { DynamicallyAccessedMemberTypes annotation = flowAnnotations.GetTypeAnnotation(type); Debug.Assert(annotation != DynamicallyAccessedMemberTypes.None); + + // We're on an interface and we're processing annotations for the purposes of a object.GetType() call. + // Most of the annotations don't apply to the members of interfaces - the result of object.GetType() is + // never the interface type, it's a concrete type that implements the interface. Limit this to the only + // annotations that are applicable in this situation. + if (type.IsInterface) + { + // .All applies to interface members same as to the type + if (annotation != DynamicallyAccessedMemberTypes.All) + { + // Filter to the MemberTypes that apply to interfaces + annotation &= DynamicallyAccessedMemberTypes.Interfaces; + + // If we're left with nothing, we're done + if (annotation == DynamicallyAccessedMemberTypes.None) + return new DependencyList(); + } + } + var reflectionMarker = new ReflectionMarker(logger, factory, flowAnnotations, typeHierarchyDataFlowOrigin: type, enabled: true); // We need to apply annotations to this type, and its base/interface types (recursively) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index 84e0418e3f9e43..d66f9fcc413a65 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -377,6 +377,11 @@ private void CreateNodeCaches() return new GenericStaticBaseInfoNode(type); }); + _objectGetTypeCalled = new NodeCache(type => + { + return new ObjectGetTypeCalledNode(type); + }); + _objectGetTypeFlowDependencies = new NodeCache(type => { return new ObjectGetTypeFlowDependenciesNode(type); @@ -1147,6 +1152,12 @@ internal GenericStaticBaseInfoNode GenericStaticBaseInfo(MetadataType type) return _genericStaticBaseInfos.GetOrAdd(type); } + private NodeCache _objectGetTypeCalled; + internal ObjectGetTypeCalledNode ObjectGetTypeCalled(MetadataType type) + { + return _objectGetTypeCalled.GetOrAdd(type); + } + private NodeCache _objectGetTypeFlowDependencies; internal ObjectGetTypeFlowDependenciesNode ObjectGetTypeFlowDependencies(MetadataType type) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeCalledNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeCalledNode.cs new file mode 100644 index 00000000000000..10721729863182 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeCalledNode.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +using ILCompiler.DependencyAnalysisFramework; + +using Internal.TypeSystem; + +namespace ILCompiler.DependencyAnalysis +{ + /// + /// Represents the fact that object.GetType was called on a location typed as this + /// type or one of the subtypes of it. + /// + internal sealed class ObjectGetTypeCalledNode : DependencyNodeCore + { + private readonly MetadataType _type; + + public ObjectGetTypeCalledNode(MetadataType type) + { + _type = type; + } + + protected override string GetName(NodeFactory factory) + { + return $"Object.GetType called on {_type}"; + } + + public override IEnumerable GetStaticDependencies(NodeFactory factory) => null; + public override bool InterestingForDynamicDependencyAnalysis => false; + public override bool HasDynamicDependencies => false; + public override bool HasConditionalStaticDependencies => false; + public override bool StaticDependenciesAreComputed => true; + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; + public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; + + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeFlowDependenciesNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeFlowDependenciesNode.cs index a30e1a7dc3c555..49fa353f50e55c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeFlowDependenciesNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectGetTypeFlowDependenciesNode.cs @@ -6,6 +6,8 @@ using ILCompiler.DependencyAnalysisFramework; +using ILLink.Shared.TrimAnalysis; + using Internal.TypeSystem; namespace ILCompiler.DependencyAnalysis @@ -25,21 +27,31 @@ public ObjectGetTypeFlowDependenciesNode(MetadataType type) protected override string GetName(NodeFactory factory) { - return $"Object.GetType dependencies called on {_type}"; + return $"Object.GetType dependencies for {_type}"; } public override IEnumerable GetStaticDependencies(NodeFactory factory) { var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; + FlowAnnotations flowAnnotations = mdManager.FlowAnnotations; + + DependencyList result = Dataflow.ReflectionMethodBodyScanner.ProcessTypeGetTypeDataflow(factory, mdManager.FlowAnnotations, mdManager.Logger, _type); + + MetadataType baseType = _type.MetadataBaseType; + if (baseType != null && flowAnnotations.GetTypeAnnotation(baseType) != default) + { + result.Add(factory.ObjectGetTypeFlowDependencies(baseType), "Apply annotations to bases"); + } - // We don't mark any members on interfaces - these nodes are only used as conditional dependencies - // of other nodes. Calling `object.GetType()` on something typed as an interface will return - // something that implements the interface, not the interface itself. We're not reflecting on the - // interface. - if (_type.IsInterface) - return Array.Empty(); + foreach (DefType interfaceType in _type.RuntimeInterfaces) + { + if (flowAnnotations.GetTypeAnnotation(interfaceType) != default) + { + result.Add(factory.ObjectGetTypeFlowDependencies((MetadataType)interfaceType), "Apply annotations to interfaces"); + } + } - return Dataflow.ReflectionMethodBodyScanner.ProcessTypeGetTypeDataflow(factory, mdManager.FlowAnnotations, mdManager.Logger, _type); + return result; } public override bool InterestingForDynamicDependencyAnalysis => false; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index a301d770dc0185..fd0c4e025d65e1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -408,9 +408,19 @@ public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedD { // Check to see if we have any dataflow annotations on the type. // The check below also covers flow annotations inherited through base classes and implemented interfaces. - if (type.IsDefType - && !type.IsInterface /* "IFoo x; x.GetType();" -> this doesn't actually return an interface type */ - && FlowAnnotations.GetTypeAnnotation(type) != default) + bool hasFlowAnnotations = type.IsDefType && FlowAnnotations.GetTypeAnnotation(type) != default; + + if (hasFlowAnnotations) + { + dependencies ??= new CombinedDependencyList(); + dependencies.Add(new DependencyNodeCore.CombinedDependencyListEntry( + factory.ObjectGetTypeFlowDependencies((MetadataType)type), + factory.ObjectGetTypeCalled((MetadataType)type), + "Type exists and GetType called on it")); + } + + if (hasFlowAnnotations + && !type.IsInterface /* "IFoo x; x.GetType();" -> this doesn't actually return an interface type */) { // We have some flow annotations on this type. // @@ -428,8 +438,8 @@ public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedD // Ensure we have the flow dependencies. dependencies ??= new CombinedDependencyList(); dependencies.Add(new DependencyNodeCore.CombinedDependencyListEntry( - factory.ObjectGetTypeFlowDependencies((MetadataType)type), - factory.ObjectGetTypeFlowDependencies((MetadataType)baseType), + factory.ObjectGetTypeCalled((MetadataType)type), + factory.ObjectGetTypeCalled((MetadataType)baseType), "GetType called on the base type")); // We don't have to follow all the bases since the base MethodTable will bubble this up @@ -444,8 +454,8 @@ public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedD // Ensure we have the flow dependencies. dependencies ??= new CombinedDependencyList(); dependencies.Add(new DependencyNodeCore.CombinedDependencyListEntry( - factory.ObjectGetTypeFlowDependencies((MetadataType)type), - factory.ObjectGetTypeFlowDependencies((MetadataType)interfaceType), + factory.ObjectGetTypeCalled((MetadataType)type), + factory.ObjectGetTypeCalled((MetadataType)interfaceType), "GetType called on the interface")); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 29a917f01c68ca..954ae4124058ac 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -428,6 +428,7 @@ + diff --git a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/Dataflow.cs b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/Dataflow.cs index a75ca2bcd0c4f0..dbdbcae08372e5 100644 --- a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/Dataflow.cs +++ b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/Dataflow.cs @@ -565,10 +565,7 @@ public static void Run() // so that we can tests this doesn't lead to keeping the type. Assert.Equal(666, s_neverAllocatedTypeAskingForNonPublicMethods.GetType().CountMethods()); } - // This is not great - the GetType() call above "wished" NeverAllocatedTypeAskingForNonPublicMethods - // into existence, but it shouldn't have. We could do better here if this is a problem. - // If we do that, change this .NotNull to .Null. - Assert.NotNull(typeof(TestObjectGetTypeDataflow).GetNestedTypeSecretly(nameof(NeverAllocatedTypeAskingForNonPublicMethods))); + Assert.Null(typeof(TestObjectGetTypeDataflow).GetNestedTypeSecretly(nameof(NeverAllocatedTypeAskingForNonPublicMethods))); // Sanity check Assert.NotNull(typeof(TestObjectGetTypeDataflow).GetNestedTypeSecretly(nameof(TypeWithNonPublicMethodsKept))); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs index 71c1999c9600f8..a90bee0d79c6eb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs @@ -18,6 +18,7 @@ public static void Main () { SealedConstructorAsSource.Test (); InstantiatedGenericAsSource.Test (); + InstantiatedGenericAsSourceInstantiated.Test (); EnumTypeSatisfiesPublicFields.Test (); EnumConstraintSatisfiesPublicFields.Test (); InstantiatedTypeParameterAsSource.Test (); @@ -50,15 +51,15 @@ class InstantiatedGenericAsSource { [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] class Generic { - [ExpectedWarning ("IL2112")] + [ExpectedWarning ("IL2112", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/110563")] [RequiresUnreferencedCode (nameof (KeptForMethodParameter))] public void KeptForMethodParameter () {} - [ExpectedWarning ("IL2112")] + [ExpectedWarning ("IL2112", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/110563")] [RequiresUnreferencedCode (nameof (KeptForField))] public void KeptForField () {} - [ExpectedWarning ("IL2112")] + [ExpectedWarning ("IL2112", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/110563")] [RequiresUnreferencedCode (nameof (KeptJustBecause))] public void KeptJustBecause () {} } @@ -82,6 +83,43 @@ public static void Test () } } + class InstantiatedGenericAsSourceInstantiated + { + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + class Generic + { + [ExpectedWarning ("IL2112")] + [RequiresUnreferencedCode (nameof (KeptForMethodParameter))] + public void KeptForMethodParameter () { } + + [ExpectedWarning ("IL2112")] + [RequiresUnreferencedCode (nameof (KeptForField))] + public void KeptForField () { } + + [ExpectedWarning ("IL2112")] + [RequiresUnreferencedCode (nameof (KeptJustBecause))] + public void KeptJustBecause () { } + } + + static void TestMethodParameter (Generic instance) + { + instance.GetType ().GetMethod ("KeptForMethodParameter"); + } + + static Generic field = new Generic (); + + static void TestField () + { + field.GetType ().GetMethod ("KeptForField"); + } + + public static void Test () + { + TestMethodParameter (null); + TestField (); + } + } + class EnumTypeSatisfiesPublicFields { static void ParameterType (Enum instance) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/InstantiatedGenericEquality.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/InstantiatedGenericEquality.cs index 2c9b69c9df9734..1fe5fb5be85212 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/InstantiatedGenericEquality.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/InstantiatedGenericEquality.cs @@ -18,11 +18,11 @@ public static void Main () class GenericReturnType { - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute), By = Tool.Trimmer /* Type is needed due to IL metadata only */)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] class ReturnType { - [Kept] + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] public void Method () { } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs index 58090e4ec1c511..0152323e9ef3ca 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs @@ -1582,16 +1582,46 @@ public static void Test () } } - class AnnotatedDerived + class AnnotatedBaseInstantiated { [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptMember (".ctor()")] class Base { [Kept] public void Method () { } } - [Kept (By = Tool.Trimmer /* The object.GetType() call is statically unreachable, this could be trimmed */)] + [Kept] + [KeptBaseType (typeof (Base), By = Tool.Trimmer)] + [KeptMember (".ctor()")] + class Derived : Base + { + } + + [Kept] + static Derived derivedInstance; + + [Kept] + public static void Test () + { + derivedInstance = new Derived (); + derivedInstance.GetType ().RequiresPublicMethods (); + } + } + + class AnnotatedDerived + { + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + class Base + { + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + public void Method () { } + } + + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] [KeptBaseType (typeof (Base), By = Tool.Trimmer)] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute), By = Tool.Trimmer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] @@ -1609,14 +1639,73 @@ public static void Test () } } + class AnnotatedDerivedInstantiated + { + [Kept] + [KeptMember (".ctor()")] + class Base + { + [Kept] + public void Method () { } + } + + [Kept] + [KeptBaseType (typeof (Base))] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptMember (".ctor()")] + class Derived : Base + { + } + + [Kept] + static Derived derivedInstance; + + [Kept] + public static void Test () + { + derivedInstance = new Derived (); + derivedInstance.GetType ().RequiresPublicMethods (); + } + } + class AnnotatedInterface + { + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute), By = Tool.Trimmer)] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + interface IBase + { + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + public void Method () { } + } + + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + [KeptMember (".ctor()", By = Tool.Trimmer)] + [KeptInterface (typeof (IBase), By = Tool.Trimmer)] + class Implementation : IBase + { + } + + [Kept] + static Implementation implementationInstance; + + [Kept] + public static void Test () + { + var a = implementationInstance as IBase; + implementationInstance.GetType ().RequiresPublicMethods (); + } + } + + class AnnotatedInterfaceInstantiated { [Kept] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] interface IBase { - [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/104740 */)] + [Kept] public void Method () { } } @@ -1640,6 +1729,35 @@ public static void Test () } class AnnotatedImplementation + { + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + interface IBase + { + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + public void Method () { } + } + + [Kept (By = Tool.Trimmer /* https://github.com/dotnet/runtime/issues/110563 */)] + [KeptMember (".ctor()", By = Tool.Trimmer)] + [KeptInterface (typeof (IBase), By = Tool.Trimmer)] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute), By = Tool.Trimmer)] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + class Implementation : IBase + { + } + + [Kept] + static Implementation implementationInstance; + + [Kept] + public static void Test () + { + var a = implementationInstance as IBase; + implementationInstance.GetType ().RequiresPublicMethods (); + } + } + + class AnnotatedImplementationInstantiated { [Kept] interface IBase @@ -1672,10 +1790,14 @@ public static void Test () [Kept] public static void Test () { - AnnotatedBase.Test (); ; + AnnotatedBase.Test (); + AnnotatedBaseInstantiated.Test (); AnnotatedDerived.Test (); + AnnotatedDerivedInstantiated.Test (); AnnotatedInterface.Test (); + AnnotatedInterfaceInstantiated.Test (); AnnotatedImplementation.Test (); + AnnotatedImplementationInstantiated.Test (); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index bded9f86c640ed..1fe8f1fb827300 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -17,6 +17,7 @@ namespace Mono.Linker.Tests.Cases.Reflection [SkipKeptItemsValidation (By = Tool.NativeAot)] public class TypeHierarchyReflectionWarnings { + [ExpectedWarning ("IL2026", "--AnnotatedRUCPublicMethods--")] public static void Main () { annotatedBase.GetType ().RequiresPublicMethods (); @@ -45,8 +46,15 @@ public static void Main () var t7 = typeof (DerivedFromAnnotatedPublicParameterlessConstructor); annotatedRUCPublicMethods.GetType ().RequiresPublicMethods (); - // Instantiate this type just so its property getters are considered reachable - var b = new DerivedFromAnnotatedDerivedFromBase (); + // Instantiate these types just so things are considered reachable + _ = new DerivedFromAnnotatedDerivedFromBase (); + _ = new AnnotatedPublicMethods (); + _ = new AnnotatedPublicFields (); + _ = new AnnotatedPublicEvents (); + _ = new AnnotatedPublicProperties (); + _ = new AnnotatedInterfaces (); + _ = new AnnotatedPublicNestedTypes (); + _ = new AnnotatedRUCPublicMethods (); // Check that this field doesn't produce a warning even if it is kept // for some non-reflection access. @@ -62,8 +70,8 @@ public static void Main () RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Test (); UseByDerived.Test (); - CompilerGeneratedCodeRUC.Test (null); - CompilerGeneratedCodeDAM.Test (null); + CompilerGeneratedCodeRUC.Test (new CompilerGeneratedCodeRUC ()); + CompilerGeneratedCodeDAM.Test (new CompilerGeneratedCodeDAM ()); } [Kept] @@ -152,6 +160,7 @@ class DerivedFromAnnotatedAllWithInterface : AnnotatedAll, InterfaceImplementedB } [Kept] + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] class AnnotatedPublicMethods @@ -204,6 +213,7 @@ Type type } [Kept] + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] class AnnotatedPublicFields @@ -217,6 +227,7 @@ class AnnotatedPublicFields } [Kept] + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] class AnnotatedPublicProperties @@ -237,6 +248,7 @@ public static string DAMProperty { } [Kept] + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] class AnnotatedPublicEvents @@ -272,6 +284,7 @@ interface RequiredInterface } [Kept] + [KeptMember (".ctor()")] [KeptInterface (typeof (RequiredInterface))] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] @@ -497,6 +510,7 @@ public class BaseTypeOfNestedType public void RUCMethod () { } } + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] // Warnings about base types of nested types are shown at the (outer) type level. @@ -595,6 +609,7 @@ public class NestedType : AnnotatedBaseSharedByNestedTypes [RequiresUnreferencedCode ("--AnnotatedRUCPublicMethods--")] public class AnnotatedRUCPublicMethods { + [Kept] public AnnotatedRUCPublicMethods () { } [Kept] @@ -702,7 +717,7 @@ public class Base [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] - [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/104740")] + [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] public virtual void RUCVirtualMethod () { } } @@ -740,7 +755,7 @@ public interface Interface [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RUCOnVirtualOnAnnotatedInterface.Interface.RUCVirtualMethod--")] - [ExpectedWarning ("IL2112", "--RUCOnVirtualOnAnnotatedInterface.Interface.RUCVirtualMethod--", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/104740")] + [ExpectedWarning ("IL2112", "--RUCOnVirtualOnAnnotatedInterface.Interface.RUCVirtualMethod--")] void RUCVirtualMethod () { } } @@ -778,7 +793,7 @@ public interface Interface [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Interface.RUCVirtualMethod--")] - [ExpectedWarning ("IL2112", "--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Interface.RUCVirtualMethod--", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/104740")] + [ExpectedWarning ("IL2112", "--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Interface.RUCVirtualMethod--")] void RUCVirtualMethod () { } } @@ -821,7 +836,7 @@ class AnnotatedBase [RequiresUnreferencedCode ("--AnnotatedBase.VirtualMethodWithRequires--")] [RequiresDynamicCode ("--AnnotatedBase.VirtualMethodWithRequires--")] [RequiresAssemblyFiles ("--AnnotatedBase.VirtualMethodWithRequires--")] - [ExpectedWarning ("IL2112", "--AnnotatedBase.VirtualMethodWithRequires--", Tool.Trimmer | Tool.Analyzer, "https://github.com/dotnet/runtime/issues/104740")] + [ExpectedWarning ("IL2112", "--AnnotatedBase.VirtualMethodWithRequires--")] public virtual void VirtualMethodWithRequires () { } } @@ -900,6 +915,7 @@ public static void Test () class CompilerGeneratedBackingField { [Kept] + [KeptMember (".ctor()")] public class BaseWithField { [KeptBackingField] @@ -908,6 +924,7 @@ public class BaseWithField } [Kept] + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [KeptBaseType (typeof (BaseWithField))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] @@ -923,6 +940,7 @@ public class DerivedWithAnnotation : BaseWithField [Kept] public static void Test () { + derivedInstance = new DerivedWithAnnotation (); derivedInstance.GetType ().RequiresNonPublicFields (); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs index 49d9b13bf9ca91..2120d4afea2373 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs @@ -27,6 +27,7 @@ public static void Main () // derived types to access annotated methods without any warnings: derivedFromSuppressed.GetType ().GetMethod ("RUCDerivedMethod"); + _ = new AnnotatedAllSuppressed (); } [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index f9a97cfffdccd1..da4fbcd59c330e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -821,13 +821,15 @@ static void TestDAMAccessOnInstantiatedGeneric () } [ExpectedWarning ("IL2026", "--TestDAMOnTypeAccessInRUCScope--")] + [ExpectedWarning ("IL2026", "DAMAnnotatedClass.DAMAnnotatedClass()")] + [ExpectedWarning ("IL3050", "DAMAnnotatedClass.DAMAnnotatedClass()", Tool.NativeAot | Tool.Analyzer, "")] public static void Test () { TestDAMAccess (); TestDirectReflectionAccess (); TestDynamicDependencyAccess (); - TestDAMOnTypeAccess (null); - TestDAMOnTypeAccessInRUCScope (); + TestDAMOnTypeAccess (new DAMAnnotatedClass ()); + TestDAMOnTypeAccessInRUCScope (new DAMAnnotatedClassAccessedFromRUCScope ()); TestDAMAccessOnOpenGeneric (); TestDAMAccessOnInstantiatedGeneric (); } @@ -1208,12 +1210,14 @@ static void TestDAMOnTypeAccess (DAMAnnotatedClass instance) instance.GetType ().GetProperty ("publicProperty"); } + [ExpectedWarning ("IL2026", "DAMAnnotatedClass.DAMAnnotatedClass()")] + [ExpectedWarning ("IL3050", "DAMAnnotatedClass.DAMAnnotatedClass()", Tool.NativeAot | Tool.Analyzer, "")] public static void Test () { TestDAMAccess (); TestDirectReflectionAccess (); TestDynamicDependencyAccess (); - TestDAMOnTypeAccess (null); + TestDAMOnTypeAccess (new DAMAnnotatedClass ()); } } From 040cbe276907174316e2cc07b35814b3069874a6 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 17 Dec 2024 16:07:01 +0100 Subject: [PATCH 7/7] [wasm] Fix templates patch in the bench (#110779) The templates were updated recently. It also updates the copying of the files again as the tfm's are in sync now. --- src/mono/sample/wasm/blazor-frame/blazor-frame.diff | 4 ++-- .../wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mono/sample/wasm/blazor-frame/blazor-frame.diff b/src/mono/sample/wasm/blazor-frame/blazor-frame.diff index c57ea7d76a04e9..a5318678e99abd 100644 --- a/src/mono/sample/wasm/blazor-frame/blazor-frame.diff +++ b/src/mono/sample/wasm/blazor-frame/blazor-frame.diff @@ -42,7 +42,7 @@ diff -urw blazor/blazor.csproj blazor/blazor.csproj --- a/blazor/blazor.csproj 2024-01-22 16:01:30 +++ b/blazor/blazor.csproj 2024-01-23 12:04:59 @@ -4,6 +4,8 @@ - net9.0 + net10.0 enable enable + blazor-template/ @@ -59,7 +59,7 @@ diff -urw blazor/wwwroot/index.html blazor/wwwroot/index.html blazor - + - + @@ -23,10 +23,11 @@ diff --git a/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj b/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj index 7ff54dab058516..5214b939681939 100644 --- a/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj +++ b/src/mono/sample/wasm/browser-bench/Wasm.Browser.Bench.Sample.csproj @@ -106,7 +106,7 @@ - + - +