-
Couldn't load subscription status.
- Fork 1.4k
Make StronglyTypedResourceGenerator work on .NET Core #3819
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
Methods that used WinForms-specific resx BCL types have been #if'ed out to throw NotImplementedException on .NET Core. They will be more fully implemented in the next series of commits.
This helps work with non-string types in resx files.
|
Note that |
|
I think I've fixed ResXFileRef support, but I'm not certain. |
|
@nguerrera and @Tanya-Solyanik, do you have thoughts about this approach of reimplementing some of the resx reading instead of (I assume until) we can wait to get |
| while (!type.IsPublic) | ||
| { | ||
| type = type.BaseType; | ||
| } |
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.
It's not clear to me why this can be deleted. Won't it break existing uses?
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.
It had to be deleted because I'm no longer operating on types. I am dealing with the full names of types as strings, because MSBuild might not have access to the types (such as Bitmap) that the user is placing in their resx file.
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.
I see that. I think we would have to leave the prior behavior on full-framework msbuild with more conditional compilation. :(
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.
yeah, I'm afraid so :(
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.
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.
Just my 2 cents, but I feel it would be really useful to have implementations of System.Resources.IResourceReader and System.Resources.IResourceWriter available to MSBuild and cross-platform (hopefully wrapped as a .netstandard package so it can fall through to the full framework or use a custom implementation etc.)
I believe that EF6 will need this as part of its porting.
|
@rainersigwald I don't have a strong opinion. If the amount of code required is small (seems so here), I think it's reasonable to duplicate. Otherwise, I think we'd want to push the resx stuff down from System.Windows.Forms to base shared framework somewhere. |
|
@nguerrera @rainersigwald In all honesty, this is still a very, very rough first draft. Any and all advice on how to improve this PR will be appreciated. |
Per PR review. I have tested this locally, and it works, but I don't know it if meets compatibility requirements or not.
I had to add a reference to the ConfigurationManager package so that the ConfigurationException thrown by the CodeDomProvider can be properly handled. This in turn required that I bump the version of the System.Security.Principal.Windows package.
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.
I'm happy to see the PR. In PowerShell repo we use a workaround some years. I hope the PR will successfully finished.
I don't see xUnit tests so I'd consider shared code with WinForm too.
Co-Authored-By: wjk <wjk011@gmail.com>
Co-Authored-By: wjk <wjk011@gmail.com>
Sometimes (such as in the test resx file I'm using), the strings used in the resx file can be very long. Note that I don't know how much this fix changes the doc comment generation behavior from what it was before (if, indeed, it changed at all).
|
I think I've figured out the failing unit test. The problem is that the value returned by the @rainersigwald @nguerrera Could you (or whomever else has an idea) please chime in with some thoughts? I don't see a way to fix this test, but I may be missing something obvious. Thanks! |
|
Could someone please help me out with the failing CI? I keep getting ~70 unit test failures, even after reverting the change I made in e45c285. All of these tests pass when I run them locally on my dev box. I am at my wits' end here, and I want to get this PR merged sooner rather than later so it can be ready for the Core 3.0 official preview. |
|
I can reproduce some of the failures with On full framework, On core: <test name="Microsoft.Build.UnitTests.WriteCodeFragment_Tests.InvalidLanguage" type="Microsoft.Build.UnitTests.WriteCodeFragment_Tests" method="InvalidLanguage" time="0.0014599" result="Fail">
<traits>
<trait name="Category" value="mono-osx-failing" />
</traits>
<failure exception-type="System.CodeDom.Compiler.CodeDomProvider+ConfigurationErrorsException">
<message><![CDATA[System.CodeDom.Compiler.CodeDomProvider+ConfigurationErrorsException : There is no CodeDom provider defined for the language.]]></message>
<stack-trace><![CDATA[ at System.CodeDom.Compiler.CodeDomProvider.GetCompilerInfo(String language)
at System.CodeDom.Compiler.CodeDomProvider.CreateProvider(String language)
at Microsoft.Build.Tasks.WriteCodeFragment.GenerateCode(String& extension) in /_/src/Tasks/WriteCodeFragment.cs:line 140
at Microsoft.Build.Tasks.WriteCodeFragment.Execute() in /_/src/Tasks/WriteCodeFragment.cs:line 84
at Microsoft.Build.UnitTests.WriteCodeFragment_Tests.InvalidLanguage() in S:\msbuild\src\Tasks.UnitTests\WriteCodeFragment_Tests.cs:line 34]]></stack-trace>
</failure>
</test>
<test name="Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.RequiredTransformations.STRWithResourcesNamespaceVB" type="Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.RequiredTransformations" method="STRWithResourcesNamespaceVB" time="0.0882194" result="Fail">
<output><![CDATA[resgen.exe C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmpbedb2c14b77e4be3b605675e84a9533a.txt C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmpbedb2c14b77e4be3b605675e84a9533a.resources /str:VB,,,
Processing resource file "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmpbedb2c14b77e4be3b605675e84a9533a.txt" into "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmpbedb2c14b77e4be3b605675e84a9533a.resources".
Processing 4 resources from file "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmpbedb2c14b77e4be3b605675e84a9533a.txt".
Creating strongly typed resources class "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmpbedb2c14b77e4be3b605675e84a9533a.vb".
]]></output>
<traits>
<trait name="Category" value="mono-osx-failing" />
<trait name="Category" value="mono-windows-failing" />
</traits>
<failure exception-type="Xunit.Sdk.TrueException">
<message><![CDATA[Assert.True() Failure\r\nExpected: True\r\nActual: False]]></message>
<stack-trace><![CDATA[ at Microsoft.Build.UnitTests.GenerateResource_Tests.Utilities.AssertStateFileWasWritten(GenerateResource t) in S:\msbuild\src\Tasks.UnitTests\GenerateResource_Tests.cs:line 3245
at Microsoft.Build.UnitTests.GenerateResource_Tests.Utilities.STRNamespaceTestHelper(String strLanguage, String resourcesNamespace, String classNamespace, ITestOutputHelper output) in S:\msbuild\src\Tasks.UnitTests\GenerateResource_Tests.cs:line 3631
at Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.RequiredTransformations.STRWithResourcesNamespaceVB() in S:\msbuild\src\Tasks.UnitTests\GenerateResource_Tests.cs:line 1258]]></stack-trace>
</failure>
</test>
<test name="Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.RequiredTransformations.STRWithResourcesNamespaceAndSTRNamespaceCS" type="Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.RequiredTransformations" method="STRWithResourcesNamespaceAndSTRNamespaceCS" time="0.0226973" result="Fail">
<output><![CDATA[resgen.exe C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmp0dc3042b713248e1b7681137c6c57fa7.txt C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmp0dc3042b713248e1b7681137c6c57fa7.resources /str:CSharp,MySTClassNamespace,,
Processing resource file "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmp0dc3042b713248e1b7681137c6c57fa7.txt" into "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmp0dc3042b713248e1b7681137c6c57fa7.resources".
Processing 4 resources from file "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmp0dc3042b713248e1b7681137c6c57fa7.txt".
Creating strongly typed resources class "C:\Users\raines\AppData\Local\Temp\ogfuf5ii.wzw\tmp0dc3042b713248e1b7681137c6c57fa7.cs".
]]></output>
<traits>
<trait name="Category" value="mono-osx-failing" />
<trait name="Category" value="mono-windows-failing" />
</traits>
<failure exception-type="Xunit.Sdk.TrueException">
<message><![CDATA[Assert.True() Failure\r\nExpected: True\r\nActual: False]]></message>
<stack-trace><![CDATA[ at Microsoft.Build.UnitTests.GenerateResource_Tests.Utilities.AssertStateFileWasWritten(GenerateResource t) in S:\msbuild\src\Tasks.UnitTests\GenerateResource_Tests.cs:line 3245
at Microsoft.Build.UnitTests.GenerateResource_Tests.Utilities.STRNamespaceTestHelper(String strLanguage, String resourcesNamespace, String classNamespace, ITestOutputHelper output) in S:\msbuild\src\Tasks.UnitTests\GenerateResource_Tests.cs:line 3631
at Microsoft.Build.UnitTests.GenerateResource_Tests.InProc.RequiredTransformations.STRWithResourcesNamespaceAndSTRNamespaceCS() in S:\msbuild\src\Tasks.UnitTests\GenerateResource_Tests.cs:line 1271]]></stack-trace>
</failure>
</test>And others. How are you running the tests? |
|
@rainersigwald I just run them using the VS Test Explorer. I did this so I could use the debugger to investigate the cause of the failures. Is this an incorrect methodology? |
Apparently, this was not the cause of the excessive test failures being seen in CI. This reverts commit e45c285.
|
As it turns out, using the VS Test Explorer was incorrect methodology. It runs the tests under the full-framework runtime, while the tests were failing only when run under the .NET Core runtime. Will have some fixes pushed up momentarily. |
This works around unit test failures on macOS and Linux that I do not have the patience to fix correctly.
|
@rainersigwald @nguerrera It's been over two weeks since I got the tests passing; I would appreciate PR review so we can get this merged soon. Thanks! 😄 |
| { | ||
| provider = CodeDomProvider.CreateProvider(stronglyTypedLanguage); | ||
| } | ||
| #if FEATURE_SYSTEM_CONFIGURATION |
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.
Elsewhere you still have configuration #if'ed out. Does CodeDomProvider actually throw configuration exception on .NET Core? I think we should avoid adding a dependency on it if it's not needed.
| { | ||
| provider = CodeDomProvider.CreateProvider(Language); | ||
| } | ||
| #if FEATURE_WINFORMS_RESX |
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 where it's still #if'ed out that I referenced in earlier comment)
|
|
||
| return InternalCreate(resourceList, baseName, generatedCodeNamespace, resourcesNamespace, codeProvider, internalClass, out unmatchable); | ||
| #else | ||
| throw new NotImplementedException(); |
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 should probably have a better error message describing what isn't supported.
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.
I don't know about MSBuild usage, but in CoreFX NotImplementedException is used when something is not implemented by design (such as, it needs to be overridden) and PlatformNotSupportedException when it's not relevant to the platform or not yet implemented there.
|
In general, I still find it hard to follow the impact this will have on the full-framework case. Some work was done to retain the System.Type usage, but then in some places, there are still string comparison replacing type comparisons unconditionally in other places. I think I'd have an easier time reviewing if it were more obvious that this enables core without changing behavior on framework. |
|
@nguerrera In all honesty, the string comparison was only implemented because, at the time, However, with WinForms open-sourced and ported to Core, I was planning on adding a copy of them into the Tasks project (to break the dependency on the Forms DLL; we can always remove them again later), getting rid of the string-related code, and enabling |
|
I'm not sure because there are open questions about actively instantiating objects while reading resx. I have two things in mind: get away from that, but also don't |
This is high on my agenda for next week, for reasons closely related to this PR. |
👍 @wjk, I would hold off on doing any big changes to this PR while @rainersigwald is looking into this. |
|
@nguerrera @rainersigwald Any updates? |
|
This feature would really be useful, thanks to the PR creator, I hope this gets merged downstream to the 2.2 SDK as well. |
|
Any updates @nguerrera @rainersigwald ? |
|
This PR has since been superseded by #4420. Closing. |
Title says it all, really. Have tested with the project attached below. The STR code-behind is generated containing both a string and non-string resource (a Bitmap, to be precise) and compiles successfully. Code is very messy, however; I would appreciate some advice on how it should be cleaned up. Thanks!
Relates to: #2221, dotnet/sdk#1782
msbuild_test.zip