Skip to content

Adding generation of substitution files for trimming out resources when feature switch is present #38397

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

Merged
merged 9 commits into from
Jun 30, 2020

Conversation

joperezr
Copy link
Member

@joperezr joperezr commented Jun 25, 2020

Contributes to #34057
Fixes #37587

cc: @eerhardt @tarekgh

These changes will make it such that all of the assemblies we ship which also have resources will no also contain a Substitutions file embedded such that if the user selects either the appContext switch or sets a property (that needs to be defined and added on the linker targets) on the project, then all resources will be removed and only resource keys will be used instead. I'm waiting on an arcade change in order to be able to add tests for this which will make sure that setting the runtimeconfig switch will cause this to happen but that will be added into this PR.

FYI: @danmosemsft @vitek-karas @marek-safar

@joperezr joperezr added area-System.Resources linkable-framework Issues associated with delivering a linker friendly framework labels Jun 25, 2020
@ghost
Copy link

ghost commented Jun 25, 2020

Tagging subscribers to this area: @tarekgh, @buyaa-n, @krwq
Notify danmosemsft if you want to be subscribed.

Copy link
Member

@tarekgh tarekgh left a comment

Choose a reason for hiding this comment

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

added comment/question. otherwise LGTM.

@@ -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
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
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
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
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
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.

Copy link
Member

@tarekgh tarekgh Jun 25, 2020

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
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
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

<linker>
<assembly fullname="{AssemblyName}">
<!-- System.SR.UsingResourceKeys removes resource strings and instead uses the resource key as the exception message -->
<resource name="{StringResourcesName}.resources" action="remove" feature="System.SR.UsingResourceKeys" featurevalue="true" />
Copy link
Member

Choose a reason for hiding this comment

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

"SR" sounds pretty cryptic. Is System.SR.UsingResourceKeys a good public facing name? Should it rather be System.Resources. ... ?

Copy link
Member

Choose a reason for hiding this comment

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

SR in general is internal and not public. Are you talking about the name used here in these targets? does it matter much?

Copy link
Member Author

Choose a reason for hiding this comment

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

it will be public in the sense that people can pass that in as extra args to the trimmer if they want to manually define it that way. Most people though will be instead using a property that will be added to the SDK that will control this feature switch, with a name like:

<PropertyGroup>
  <TrimResources>true</TrimResources>
</PropertyGroup>

or something like that. All that said though, I do agree with @jkotas point plus we are also using the same name witht he AppContext switch which will be definitely "more public" as people will be setting this on their runtimeconfig file. I will change the name.

Copy link
Member

Choose a reason for hiding this comment

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

One concern I have with System.Resources.UseResourceKeys is that it sounds like it affects all resources, not just the exception messages coming from the runtime.

Is there a word/term/name we can use to make it specific to the runtime resources?

  • System.Resources.UseSystemResourceKeys
  • System.Resources.UseBclResourceKeys
  • System.Resources.UseSRResourceKeys

Copy link
Member

Choose a reason for hiding this comment

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

AppContext switch which will be definitely "more public" as people will be setting this on their runtimeconfig file. I will change the name

while it's possible to set this directly in .runtimeconfig.json I don't expect many people actually doing it. We expect the vast majority to use MSBuild property to drive this.

So we need a really good "customer facing" name for the MSBuild property.
And we need a good "technical" name for the runtime option/AppContext switch.

What the options does:
When enabled, all string resources in our framework assemblies will be removed and replaced with the resource keys instead. Framework only uses string resources for exception messages (I'm not aware of any other usage), so the effect of this change is for example (aside from saving quite a bit of size):

System.ArgumentNullException: Value cannot be null. (Parameter 'args')

turns into

System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, args

Customer facing name should reflect the behavioral change - so maybe something along the lines of UseResourceKeysForExceptionMessages (this is a bad name, but the intent is there).

Technical name should be something closer to the code base, so maybe System.Resources.UseStringSystemResourceKeys...

Adding @samsp-msft who might have better ides about naming.

Copy link
Member

Choose a reason for hiding this comment

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

Framework only uses string resources for exception messages (I'm not aware of any other usage)

Here are examples of resource uses for strings that are not exception messages:

Copy link
Member

Choose a reason for hiding this comment

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

Thanks @jkotas! I guess it's OK to remove resources for those as well... it just makes the naming more complicated...

Copy link
Member

Choose a reason for hiding this comment

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

Here are examples of resource uses for strings that are not exception messages:

I assume for .NET Native, which used this same switch, those places were broken as well? For example in a StackTrace.ToString() you would get Word_At instead of at?

Copy link
Member

Choose a reason for hiding this comment

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

That's what defaultString argument of GetResourceString method was designed for. IIRC, the most egregious cases were fixed by passing in a sensible default string into this API in .NET Native. I do not remember whether Word_At got this treatment.

Copy link
Member

Choose a reason for hiding this comment

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

That's what defaultString argument of GetResourceString method was designed for.

I see. My assumption was that defaultString was hard-coded in C# during Debug builds, so we had nice exception messages when we were debugging. But I guess it would make sense to use it elsewhere as well.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

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

LGTM.

It would be great if we can analyze the places that use SR for non-exception messages to ensure we aren't breaking something there.

@joperezr
Copy link
Member Author

Merging given the only change since clean CI was fixing a typo on a test name and removing a diagnostic message in one of our targets.

@joperezr joperezr merged commit 4a683af into dotnet:master Jun 30, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
@joperezr joperezr deleted the RemoveResources branch August 11, 2021 20:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Resources linkable-framework Issues associated with delivering a linker friendly framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SR.GetResourceString doesn't return resource key when UsingResourceKeys is true
7 participants