Skip to content

[wasm][globalization] HybridGlobalization remove code conditionally for WasmBuildNative #87170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/testing/linker/trimmingTests.targets
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
<Output TaskParameter="ExitCode" PropertyName="ExecutionExitCode" />
</Exec>

<Error Condition="'$(ExecutionExitCode)' != '100'" Text="Error: [Failed Test]: %(TestConsoleApps.ProjectCompileItems). The Command %(TestConsoleApps.TestCommand) return a non-success exit code." ContinueOnError="ErrorAndContinue" />
<Error Condition="'$(ExecutionExitCode)' != '100'" Text="Error: [Failed Test]: %(TestConsoleApps.ProjectCompileItems). The Command %(TestConsoleApps.TestCommand) return a non-success exit code: $(ExecutionExitCode)." ContinueOnError="ErrorAndContinue" />
</Target>

<Target Name="Build" DependsOnTargets="ExecuteApplications" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<linker>
<assembly fullname="System.Private.CoreLib">
<type fullname="System.Globalization.GlobalizationMode">
<method signature="System.Boolean get_Hybrid()" body="stub" value="true" feature="System.Globalization.Hybrid" featurevalue="false" />
<!-- non-Hybrid mode -->
<type fullname="System.Globalization.GlobalizationMode" feature="System.Globalization.Hybrid" featurevalue="false">
<method signature="System.Boolean get_Hybrid()" body="stub" value="false" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ internal unsafe void JsChangeCase(char* src, int srcLen, char* dstBuffer, int ds
{
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(!GlobalizationMode.UseNls);
#if TARGET_BROWSER
Debug.Assert(GlobalizationMode.Hybrid);
#endif

int exception;
object ex_result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// 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.Globalization;
using System.Reflection;
using System.Linq;

/// <summary>
/// Ensures setting HybridGlobalization = false still works in a trimmed app.
/// </summary>
class Program
{
static int Main(string[] args)
{
const BindingFlags allStatics = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;

try
{
CompareInfo compInfo = new CultureInfo("tr-TR").CompareInfo;
SortKey sk = compInfo.GetSortKey("string");
}
catch (PlatformNotSupportedException)
{
return -1; // we do not expect GetSortKey to throw.
}

// Ensure the internal GlobalizationMode class is trimmed correctly.
Type globalizationMode = GetCoreLibType("System.Globalization.GlobalizationMode");

var hybridFields = globalizationMode.GetMembers(allStatics).Where(member => member is FieldInfo field && field.Name.Contains("Hybrid"));
// expecting 'Hybrid' field to be trimmed
if (hybridFields.Count() != 0)
return -2;

// expecting 'get_Hybrid' property to be trimmed
var hybridProperties = globalizationMode.GetMembers(allStatics).Where(member => member is FieldInfo field && field.Name.Contains("get_Hybrid"));
if (hybridProperties.Count() != 0)
return -3;

// Ensure the CompareInfo class is trimmed correctly.
Type compareInfo = GetCoreLibType("System.Globalization.CompareInfo");

const BindingFlags privateInstanceMethods = BindingFlags.NonPublic | BindingFlags.Instance;
string[] expectedTrimmedInstatnceMethods = new string[] {
"JsInit",
"JsCompareString",
"JsStartsWith",
"JsEndsWith",
"JsIndexOfCore"
};
if (compareInfo.GetMembers(privateInstanceMethods).Any(m =>
expectedTrimmedInstatnceMethods.Any(trimmable =>
trimmable == m.Name)))
return -4;

const BindingFlags privateStaticMethods = BindingFlags.NonPublic | BindingFlags.Static;
string[] expectedTrimmedStaticeMethods = new string[] {
"AssertHybridOnWasm",
"AssertComparisonSupported",
"AssertIndexingSupported",
"IndexingOptionsNotSupported",
"CompareOptionsNotSupported",
"CompareOptionsNotSupportedForCulture",
"GetPNSEForCulture"
};
if (compareInfo.GetMembers(privateStaticMethods).Any(m =>
expectedTrimmedStaticeMethods.Any(trimmable =>
trimmable == m.Name)))
return -5;

// Ensure the TextInfo class is trimmed correctly.
Type textInfo = GetCoreLibType("System.Globalization.TextInfo");
if (textInfo.GetMembers(privateInstanceMethods).Any(m =>
m.Name == "JsChangeCase"))
return -6;

return 100;
}

// The intention of this method is to ensure the trimmer doesn't preserve the Type.
private static Type GetCoreLibType(string name) =>
typeof(object).Assembly.GetType(name, throwOnError: false);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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.Globalization;
using System.Reflection;
using System.Linq;

/// <summary>
/// Ensures setting HybridGlobalization = true still works in a trimmed app.
/// </summary>
class Program
{
static int Main(string[] args)
{
const BindingFlags allStatics = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;

try
{
CompareInfo compInfo = new CultureInfo("tr-TR").CompareInfo;
SortKey sk = compInfo.GetSortKey("string");
return -1; // we expect GetSortKey to throw.
}
catch (PlatformNotSupportedException)
{
}

// Ensure the internal GlobalizationMode class is trimmed correctly.
Type globalizationMode = GetCoreLibType("System.Globalization.GlobalizationMode");

var hybridMembers = globalizationMode.GetMembers(allStatics).Where(member =>
(member is MemberInfo m && (m.Name.StartsWith("get_Hybrid") || m.Name.StartsWith("Hybrid"))));

// expecting 'Hybrid' field and 'get_Hybrid' property
if (hybridMembers.Count() != 2)
return -2;

return 100;
}

// The intention of this method is to ensure the trimmer doesn't preserve the Type.
private static Type GetCoreLibType(string name) =>
typeof(object).Assembly.GetType(name, throwOnError: false);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
<TestConsoleAppSourceFiles Include="DebuggerVisualizerAttributeTests.cs" />
<TestConsoleAppSourceFiles Include="DefaultValueAttributeCtorTest.cs" />
<TestConsoleAppSourceFiles Include="GenericArraySortHelperTest.cs" />
<TestConsoleAppSourceFiles Include="InheritedAttributeTests.cs" />
<TestConsoleAppSourceFiles Include="InterfacesOnArrays.cs" />
<TestConsoleAppSourceFiles Include="InvariantGlobalizationFalse.cs">
<DisabledFeatureSwitches>System.Globalization.Invariant</DisabledFeatureSwitches>
<TestConsoleAppSourceFiles Include="HybridGlobalizationTrue.cs">
<EnabledFeatureSwitches>System.Globalization.Hybrid</EnabledFeatureSwitches>
</TestConsoleAppSourceFiles>
<TestConsoleAppSourceFiles Include="HybridGlobalizationFalse.cs">
<DisabledFeatureSwitches>System.Globalization.Hybrid</DisabledFeatureSwitches>
</TestConsoleAppSourceFiles>
<TestConsoleAppSourceFiles Include="InheritedAttributeTests.cs" />
<TestConsoleAppSourceFiles Include="InterfacesOnArrays.cs" />
<TestConsoleAppSourceFiles Include="InvariantGlobalizationFalse.cs">
<DisabledFeatureSwitches>System.Globalization.Invariant</DisabledFeatureSwitches>
</TestConsoleAppSourceFiles>
<TestConsoleAppSourceFiles Include="InvariantGlobalizationTrue.cs">
<DisabledFeatureSwitches>System.Globalization.Hybrid</DisabledFeatureSwitches>
<EnabledFeatureSwitches>System.Globalization.Invariant;System.Globalization.PredefinedCulturesOnly</EnabledFeatureSwitches>
</TestConsoleAppSourceFiles>
<TestConsoleAppSourceFiles Include="StackFrameHelperTest.cs">
Expand Down