Skip to content
Merged
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
10 changes: 10 additions & 0 deletions eng/ILLink.Substitutions.Resources.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<linker>
<!-- System.Resources.UseSystemResourceKeys removes resource strings and instead uses the resource key as the exception message -->
<assembly fullname="{AssemblyName}" feature="System.Resources.UseSystemResourceKeys" featurevalue="true">
<!-- System.Resources.UseSystemResourceKeys removes resource strings and instead uses the resource key as the exception message -->
<resource name="{StringResourcesName}.resources" action="remove" />
<type fullname="System.SR">
<method signature="System.Boolean UsingResourceKeys()" body="stub" value="true" />
</type>
</assembly>
</linker>
37 changes: 34 additions & 3 deletions eng/illink.targets
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
<ILLinkTrimXmlLibraryBuild Condition="'$(ILLinkTrimXmlLibraryBuild)' == '' and Exists('$(MSBuildProjectDirectory)/ILLinkTrim_LibraryBuild.xml')">$(MSBuildProjectDirectory)/ILLinkTrim_LibraryBuild.xml</ILLinkTrimXmlLibraryBuild>
<ILLinkDescriptorsXmlIntermediatePath>$(IntermediateOutputPath)ILLink.Descriptors.xml</ILLinkDescriptorsXmlIntermediatePath>

<ILLinkSubstitutionsXml Condition="'$(ILLinkSubstitutionsXml)' == '' and Exists('$(MSBuildProjectDirectory)/ILLink.Substitutions.xml')">$(MSBuildProjectDirectory)/ILLink.Substitutions.xml</ILLinkSubstitutionsXml>
<ILLinkSubstitutionsXmlIntermediatePath>$(IntermediateOutputPath)ILLink.Substitutions.xml</ILLinkSubstitutionsXmlIntermediatePath>

<!-- if building a PDB, tell illink to rewrite the symbols file -->
Expand All @@ -49,7 +48,6 @@

<ItemGroup>
<None Include="$(ILLinkTrimXmlLibraryBuild)" Condition="'$(ILLinkTrimXmlLibraryBuild)' != ''" />
<None Include="$(ILLinkSubstitutionsXml)" Condition="'$(ILLinkSubstitutionsXml)' != ''" />
<None Include="@(ILLinkSubstitutionsXmls)" />
</ItemGroup>

Expand Down Expand Up @@ -105,8 +103,41 @@
</ItemGroup>
</Target>

<PropertyGroup>
<ILLinkResourcesSubstitutionIntermediatePath>$(IntermediateOutputPath)ILLink.Resources.Substitutions.xml</ILLinkResourcesSubstitutionIntermediatePath>
<GenerateResourcesSubstitutions Condition="'$(GenerateResourcesSubstitutions)' == '' and '$(StringResourcesPath)' != ''">true</GenerateResourcesSubstitutions>
</PropertyGroup>

<ItemGroup Condition="'$(GenerateResourcesSubstitutions)' == 'true'">
<ILLinkSubstitutionsXmls Include="$(ILLinkResourcesSubstitutionIntermediatePath)" />
</ItemGroup>

<!-- If a library uses string resources, the following target generates a substitution xml that will be embedded on the
library so that if a consumer wants to run the linker they can specify a feature switch to strip out all resources
from the assembly. -->
<Target Name="GenerateResourcesSubstitutionFile"
Condition="'$(GenerateResourcesSubstitutions)' == 'true'"
Inputs="$(MSBuildProjectFullPath)"
Outputs="$(ILLinkResourcesSubstitutionIntermediatePath)">

<PropertyGroup>
<ILLinkResourcesSubstitutionTemplate>$(MSBuildThisFileDirectory)ILLink.Substitutions.Resources.template</ILLinkResourcesSubstitutionTemplate>
</PropertyGroup>

<WriteLinesToFile File="$(ILLinkResourcesSubstitutionIntermediatePath)"
Lines="$([System.IO.File]::ReadAllText('$(ILLinkResourcesSubstitutionTemplate)')
Comment thread
joperezr marked this conversation as resolved.
Outdated
.Replace('{AssemblyName}', '$(AssemblyName)')
.Replace('{StringResourcesName}', '$(StringResourcesName)'))"
Overwrite="true" />

<ItemGroup>
<FileWrites Include="$(ILLinkResourcesSubstitutionIntermediatePath)" />
</ItemGroup>
</Target>

<Target Name="_CombineILLinkSubstitutionsXmls"
Condition="'$(ILLinkSubstitutionsXml)' == '' and '@(ILLinkSubstitutionsXmls)' != ''"
DependsOnTargets="GenerateResourcesSubstitutionFile"
Condition="'@(ILLinkSubstitutionsXmls)' != ''"
Inputs="@(ILLinkSubstitutionsXmls)"
Outputs="$(ILLinkSubstitutionsXmlIntermediatePath)">
<PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions eng/testing/linker/project.csproj.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<RuntimeIdentifier>{RuntimeIdentifier}</RuntimeIdentifier>
<RuntimePackDir>{RuntimePackDir}</RuntimePackDir>
<TargetingPackDir>{TargetingPackDir}</TargetingPackDir>
<_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs)</_ExtraTrimmerArgs>
</PropertyGroup>

<!-- Logic to override the default IlLink tasks that come from the SDK and use the one
Expand Down
3 changes: 2 additions & 1 deletion eng/testing/linker/trimmingTests.targets
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
.Replace('{RuntimePackDir}', '%(TestConsoleApps.RuntimePackDirectory)')
.Replace('{TargetingPackDir}','$(MicrosoftNetCoreAppRefPackDir)')
.Replace('{RuntimeIdentifier}','%(TestConsoleApps.TestRuntimeIdentifier)')
.Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)'))"
.Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)')
.Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)'))"
Overwrite="true" />
<Copy SourceFiles="$(_projectSourceFile)"
DestinationFolder="$(_projectDir)" />
Expand Down
18 changes: 12 additions & 6 deletions src/libraries/Common/src/System/SR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ namespace System
{
internal partial class SR
{
#if (!NETSTANDARD1_0 && !NETSTANDARD1_1 && !NET45) // AppContext is not supported on < NetStandard1.3 or < .NET Framework 4.5
private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out bool usingResourceKeys) ? usingResourceKeys : false;
#endif

// This method is used to decide if we need to append the exception message parameters to the message when calling SR.Format.
// by default it returns false.
// by default it returns the value of System.Resources.UseSystemResourceKeys AppContext switch or false if not specified.
// Native code generators can replace the value this returns based on user input at the time of native code generation.
// Marked as NoInlining because if this is used in an AoT compiled app that is not compiled into a single file, the user
// could compile each module with a different setting for this. We want to make sure there's a consistent behavior
// that doesn't depend on which native module this method got inlined into.
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool UsingResourceKeys() => false;
// The Linker is also capable of replacing the value of this method when the application is being trimmed.
private static bool UsingResourceKeys() =>
Comment thread
joperezr marked this conversation as resolved.
Outdated
#if (!NETSTANDARD1_0 && !NETSTANDARD1_1 && !NET45) // AppContext is not supported on < NetStandard1.3 or < .NET Framework 4.5
s_usingResourceKeys;
#else
false;
#endif

internal static string GetResourceString(string resourceKey, string? defaultString = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@
<Reference Include="System.Runtime.Extensions" />
<Reference Include="System.Threading" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<Reference Include="System.AppContext" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == '$(NetCoreAppCurrent)'">
<Reference Include="System.Runtime.InteropServices" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
<Reference Include="System.Threading" />
<Reference Include="System.Resources.ResourceManager" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<Reference Include="System.AppContext" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
<Compile Include="AssemblyInfo.netfx.cs" />
<Compile Include="System\Diagnostics\Activity.DateTime.netfx.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<IsPartialFacadeAssembly Condition="$(TargetFramework.StartsWith('net4'))">true</IsPartialFacadeAssembly>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<Reference Include="System.AppContext" />
<Reference Include="System.Collections" />
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Globalization" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<PropertyGroup>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>c5ed3c1d-b572-46f1-8f96-522a85ce1179</SharedGUID>
<StringResourcesName Condition="'$(StringResourcesName)' == ''">System.Private.CoreLib.Strings</StringResourcesName>
<GenerateResourcesSubstitutions>true</GenerateResourcesSubstitutions>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace />
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/System.Private.CoreLib/src/System/SR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static partial class SR
// Needed for debugger integration
internal static string GetResourceString(string resourceKey)
{
return GetResourceString(resourceKey, string.Empty);
return GetResourceString(resourceKey, null);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tarekgh I made this change due to the discussion #37587 (comment)

Do you mind taking a look at this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to get rid of this file and use the one in the common? we can look quickly at the differences. both should be providing the same logic. or if you want we can do that in a separate PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is extension of the common file, we cannot get rid of it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the discussion on that issue it may be that it there is a problem as some codegen from arcade might be calling this method specifically so removing might not be so simple, although I may have misinterpreted the discussion. I would prefer to scope the change to only this for now so that if Arcade gets broken by removing the method we don't have to revert this whole PR

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is extension of the common file, we cannot get rid of it

I may have misread but I thought what Tarek meant was more to remove this method, in favor of the one in the other overload defined in Common.

@tarekgh tarekgh Jun 25, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is the case, the SR.cs that in the common already have the method:

  internal static string GetResourceString(string resourceKey, string? defaultString = null)

so I guess we should delete GetResourceString from here then.


In reply to: 445786809 [](ancestors = 445786809)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the SR.cs in common is just ifdef stuff for corelib which we can get rid of now as the ResourceManager became a part of corelib already. that means we can get rid of SR.cs which is in the corelib. as I mentioned we can make this in other PR if we need to.


In reply to: 445792039 [](ancestors = 445792039,445786809)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think such change should be part of this PR

}

private static string InternalGetResourceString(string key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
<Compile Include="System\TypeLoadExceptionTests.cs" />
<Compile Include="System\TypeUnloadedExceptionTests.cs" />
<Compile Include="System\TupleTests.cs" />
<Compile Include="System\UseResourceKeysTest.cs" />
<Compile Include="System\UInt16Tests.cs" />
<Compile Include="System\UInt32Tests.cs" />
<Compile Include="System\UInt64Tests.cs" />
Expand Down
50 changes: 50 additions & 0 deletions src/libraries/System.Runtime/tests/System/UseResourceKeysTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.DotNet.RemoteExecutor;
using Xunit;

namespace System.Runtime.Tests
{
public class UseResourceKeysTest
{
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void ReturnsResourceKeyWhenFeatureSwitchIsEnabled()
{
RemoteInvokeOptions options = new RemoteInvokeOptions();
options.RuntimeConfigurationOptions.Add("System.Resources.UseSystemResourceKeys", true);

RemoteExecutor.Invoke(() =>
{
try
{
throw new AggregateException();
}
catch (Exception e)
{
Assert.Equal("AggregateException_ctor_DefaultMessage", e.Message);
}
}, options).Dispose();
}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void ReturnsResourceWhenFeatureSwitchIsDisabled()
{
RemoteInvokeOptions options = new RemoteInvokeOptions();
options.RuntimeConfigurationOptions.Add("System.Resources.UseSystemResourceKeys", false);

RemoteExecutor.Invoke(() =>
{
try
{
throw new ArgumentException();
}
catch (Exception e)
{
Assert.NotEqual("AggregateException_ctor_DefaultMessage", e.Message);
}
}, options).Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
linker repo here: https://github.com/mono/linker/issues/1285 -->
<AdditionalArgs>/p:DebugType=Embedded</AdditionalArgs>
</TestConsoleAppSourceFiles>
<TestConsoleAppSourceFiles Include="VerifyResourcesGetTrimmedTest.cs">
<!-- Setting the Trimming feature switch to make sure that the Resources get trimmed by the linker
as this test will ensure exceptions are using Resource keys -->
<ExtraTrimmerArgs>--feature System.Resources.UseSystemResourceKeys true</ExtraTrimmerArgs>
</TestConsoleAppSourceFiles>
</ItemGroup>

<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets))" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;

class Program
{
static int Main(string[] args)
{
try
{
throw new AggregateException();
}
catch (Exception e)
{
// When the Trimmer recieves the feature switch to use resource keys then exception
// messages shouldn't return the exception message resource, but instead the resource
// key. This test is passing in the feature switch so we make sure that the resources
// got trimmed correctly.
if (e.Message == "AggregateException_ctor_DefaultMessage")
{
return 100;
}
else
{
return -1;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
Link="Common\System\Collections\Concurrent\SingleProducerConsumerQueue.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.AppContext" Condition="'$(TargetFramework)' == 'netstandard1.3'" />
<Reference Include="System.Collections" />
<Reference Include="System.Collections.Concurrent" />
<Reference Include="System.Diagnostics.Debug" />
Expand Down