-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Build time ResX code-behind generation #1782
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
Conversation
|
I have also taken the liberty of using the comment entered in the ResX editor (or in the I have been wishing that VS would do this for me for many years. Since we are finally rewriting the ResX generator, I figured that this would be a good opportunity to add this functionality. |
|
@wjk Sorry for the delay in looking at this and thank you for working on it. I won't be able to review in detail until after the holidays, but let me at least answer this now to unblock ad-hoc testing:
You can run build\dogfood.cmd for this after you have done a build. This will set up a powershell session with environment variables such that That script was broken recently, so you'll want to merge with latest master first. |
|
|
||
| // If the comment was provided by the developer, use that. | ||
| // Otherwise, generate a default comment like the old ResX generator does. | ||
| if (comment == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In our own usage, comments are usually notes to translators. I think it would be useful to see both the English text AND the comment in quick info.
|
|
||
| try | ||
| { | ||
| if (Language.ToUpperInvariant() == "C#") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Language.Equals("C#", StringComparison.OrdinalIgnoreCase)
| foreach (var line in escapedTrimmedValue.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)) | ||
| builder.AppendLine($"{memberIndent}/// {line}"); | ||
|
|
||
| string identifier = IsLetterCharacter(name[0]) ? name : "_" + name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only one case of an invalid identifier. I will see if we can find the code from the CodeDOM-based generator in order to get parity with it. I see that it knows to make "a b", "a_b", and even "for" into "_for".
| { | ||
| string name = node.Attribute("name")?.Value ?? throw new InvalidDataException("Missing resource name"); | ||
| string value = node.Elements("value").FirstOrDefault()?.Value.Trim() ?? throw new InvalidDataException($"Missing resource value: '{name}'"); | ||
| string comment = node.Elements("comment").FirstOrDefault()?.Value.Trim(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another interesting case is non-string values...
04faed1 to
82dbf8c
Compare
| } | ||
| else | ||
| { | ||
| throw new BuildErrorException($"Unrecognized language '{Language}'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be any plans to support F# for ResX code-generation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kant2002 Not in this PR, I'm afraid; I don't know a thing about F#. Sorry about that!
|
MSBuild has Would it make sense to extend msbuild itself for non- |
|
And then add defaults for the metadata items for the strongly typed resource attributes in the SDK. |
|
@dasMulli I can certainly try that approach; however, I will need to copy and modify the task code to make it fully work as desired here. If that's OK, then I'd love to try it! |
These are not yet wired up into any *.targets files, nor are they tested as of this commit.
Also implemented a first stab at disabling code-behind generation for ResX files for which doing so is undesirable (e.g. WinForms form resource files).
This fix can be removed when <dotnet#1199> is resolved, and when the Visual Studio code that maintains these files is disabled when using the SDK-based project system.
280ff49 to
bdb277f
Compare
Note that this code still has not yet been tested.
|
Update on the state of this PR:
Thanks! |
|
The xsd that drives intellisense for project files is in the msbuild repo at https://github.com/Microsoft/msbuild/blob/master/src/MSBuild/Microsoft.Build.CommonTypes.xsd |
|
@nguerrera @kant2002 Some help with writing automated unit tests for this functionality would be appreciated. Thanks! |
This broke localized resources in sattelite assemblies.
Previously, any usage of a resx files in an F# project would cause a build error. Now, the error will only occur if the GenerateResxCodeBehind code is to be invoked.
|
@wjk I missed some earlier notifications that you were working on this again. Sorry about that. The general topic of resx-related features is heating up with the coming support for winforms on Core. For example, this is being looked at actively: dotnet/msbuild#2221 I think in this context, the approach @dasMulli outlined above makes a ton of sense. I believe it may even be possible to use CodeDom now on core. I would suggest taking this in 3 steps:
(3) could possibly be for SDK project only, but I think (1) and (2) should be done in msbuild. By sharing the code, we can tackle issues like non-string resources and escaping keyword as they've been tackled before and all in one place. @rainersigwald What do you think about this approach? @wjk Thank you for pushing on this. I'm extremely supportive of the user experience this provides, and I just want us to get it done with the right architecture. |
|
As far as testing, you could do something like sdk/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantAllResourcesInSatellite.cs Line 102 in 506c69f
But amend the test project to use generation instead of the manual call to ResourceManager:
That said, you may want to wait for our discussion on where the various pieces should go to land before investing in tests. |
|
Yes, I think but haven't validated that we can turn the CodeDOM strongly-typed stuff back on for Core now. Since the generation work has been in MSBuild, I agree that that's where it should be now. |
|
Closing since we're pushing (slowly, sorry for that -- this is a tricky area) forward with the 3 step plan above, starting with dotnet/msbuild#3819 |
This is my stab at resolving #94. To use it in a project (via
dogfood.cmdor similar), do the following:<EmbeddedResource>line in the csproj to have the metadataGenerateCodeBehind="true".$(IntermediateOutputDir)and be available to IntelliSense.Other things to note:
DocCommentModemetadata. You can set it toNoneto disable the doc comment entirely,ResxCommentto use the comment set in the VS resx editor, or toContent(the default) to use the content of the string resource, unaltered.