-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Add RegexGenerator to System.ComponentModel.TypeConverter. #62325
Add RegexGenerator to System.ComponentModel.TypeConverter. #62325
Conversation
Added to src, not to test (no test found)
Tagging subscribers to this area: @dotnet/area-system-componentmodel Issue DetailsAdded generator to source library, not to tests (no tests found)
|
Seems reasonable to me -- @stephentoub style OK for you? Cool that this will be our first use in actual product. |
...braries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerVerb.cs
Outdated
Show resolved
Hide resolved
...braries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerVerb.cs
Outdated
Show resolved
Hide resolved
@@ -261,5 +261,6 @@ | |||
<Reference Include="System.Threading" /> | |||
<Reference Include="System.Threading.Thread" /> | |||
<Reference Include="System.Xml.XDocument" /> | |||
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.RegularExpressions/gen/System.Text.RegularExpressions.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> |
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.
Why is this needed? If memory serves, we don't modify every project to be able to use e.g. DllImportGenerator. I believe it's configured in a central location to be usable everywhere.
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.
See
runtime/eng/generators.targets
Lines 9 to 30 in cc2cb04
<EnabledGenerators Include="DllImportGenerator" Condition="'$(EnableDllImportGenerator)' == 'true'" /> | |
<!-- If the current project is not System.Private.CoreLib, we enable the DllImportGenerator source generator | |
when the project is a C# source project that either: | |
- references System.Private.CoreLib, or | |
- references System.Runtime.InteropServices --> | |
<EnabledGenerators Include="DllImportGenerator" | |
Condition="'$(EnableDllImportGenerator)' == '' | |
and '$(IsFrameworkSupportFacade)' != 'true' | |
and '$(IsSourceProject)' == 'true' | |
and '$(MSBuildProjectExtension)' == '.csproj' | |
and ( | |
('@(Reference)' != '' | |
and @(Reference->AnyHaveMetadataValue('Identity', 'System.Runtime.InteropServices'))) | |
or ('@(ProjectReference)' != '' | |
and @(ProjectReference->AnyHaveMetadataValue('Identity', '$(CoreLibProject)'))))" /> | |
<EnabledGenerators Include="DllImportGenerator" | |
Condition="'$(EnableDllImportGenerator)' == '' | |
and '$(IsFrameworkSupportFacade)' != 'true' | |
and '$(IsSourceProject)' == 'true' | |
and '$(MSBuildProjectExtension)' == '.csproj' | |
and ('$(TargetFrameworkIdentifier)' == '.NETStandard' or '$(TargetFrameworkIdentifier)' == '.NETFramework')" /> | |
</ItemGroup> |
for how that works.
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, instead of having individual ProjectReferences on each project that uses it, we should instead update generators.targets to have all projects be able to consume the source generator.
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.
Ah, thanks.
I originally did it as a project reference because I ran across the dll one in a PR, before I saw the recommendations. But yes, this would be much better.
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've changed to adding the targets to that file, and it works, but I'm not very experienced with some of the more arcane things in build files. I know this is going to be reviewed anyways, but please be thorough.
I understand it might be hard to do for every one of these PRs, but it would be cool to have a sense of the specific case perf gains out of onboarding the source generator. |
eng/generators.targets
Outdated
and '$(IsFrameworkSupportFacade)' != 'true' | ||
and '$(IsSourceProject)' == 'true' | ||
and '$(MSBuildProjectExtension)' == '.csproj' | ||
and ('$(TargetFrameworkIdentifier)' == '.NETStandard' or '$(TargetFrameworkIdentifier)' == '.NETFramework')" /> |
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.
@eerhardt and I had some offline discussions about making source generators available to frameworks where they actually can't really be consumed outside of dotnet/runtime (which is the case for the Regex one) and I believe we landed on the idea that we shouldn't do this, and instead either: a) limit the source generator to only be used on platforms where it can be consumed externally, or b) expose it to other frameworks if we would see value for adding them.
If you agree, can we limit this change to only add the source generator in the netcoreapp case? (basically remove changes from line 75-80 here)
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 fine with this, but what effect is this going to have in other areas, like tests? If a project has net48
in TargetFrameworks
, would that mean it couldn't be used there? What about tests that have PlatformDetection.IsNetFramework
?
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.
If a project has net48 in TargetFrameworks, would that mean it couldn't be used there?
Correct. That behavior aligns with our customers' experience. The same goes for netstandard2.0
and net6.0
. Only net7.0
+ targets should be able to consume the RegexGenerator.
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.
Right, so any project that is expected to reference .NetF at all can't use the generator unless we get fancy with #ifdef
s, then, which is something I'll have to consider for some of the other test projects.
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.
As an aside, while technically at the moment the generated code would likely work downlevel, changes are coming that will end up using new API surface area in .NET 7, so the generator will only be usable with .NET 7+.
@@ -63,8 +63,34 @@ | |||
and @(ProjectReference->AnyHaveMetadataValue('Identity', '$(CoreLibProject)'))))" Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\ArrayMarshaller.cs" /> | |||
</ItemGroup> | |||
|
|||
<ItemGroup> | |||
<EnabledGenerators Include="RegexGenerator" Condition="'$(EnableRegexGenerator)' == 'true'" /> |
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.
@jkoritzinsky what is the reasoning behind having an explicit path and an implicit path for adding the DLLImport generator? Is that reason also applicable to the RegexGenerator? Basically my question is: for the regexgenerator should we just simplify and only enable it whenever EnableRegexGenerator property is set to true?
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.
We needed the ItemGroup
-based path to allow us to filter adding the generator ProjectReference based on referenced projects. With MSBuild static graph (which we use for our restore functionality), we can't add a ProjectReference
in a target, so we're limited to evaluation time. Since properties are evaluated before items, we needed to do the generator reference add based on an item. The property was added for simplicity.
Once we aren't adding sources to builds (and all of the APIs the generator uses are approved) then we can significantly simplify this 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.
@jkoritzinsky it sounds like you wanted to make it automatic always and you see the property as less desirable, where @joperezr was saying the property is simpler. I do think a property is more WYSIWYG, and it seems acceptable for construction of the shared framework where we are more careful about layering/dependencies.
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.
Yes, we wanted to make DllImportGenerator enabled automatically and the property was a fallback. We wanted to enable our generator automatically since we're consuming it throughout the runtime, including CoreLib. @stephentoub expressed a desire for us to enable it for all projects (including tests) and not even having a property for opt-in/out, but until we get all of our APIs approved, that's a little difficult.
eng/generators.targets
Outdated
DependsOnTargets="ResolveProjectReferences" | ||
BeforeTargets="GenerateMSBuildEditorConfigFileShouldRun"> | ||
<PropertyGroup> | ||
<DefineConstants>$(DefineConstants);REGEXGENERATOR_ENABLED</DefineConstants> |
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 know you were just following what DllImport one is doing here, but it doesn't seem like you are using this constant now and I'd only see it useful whenever a project is multitargeting and wants to conditionally compile the implementation of the regex, which I think would probably more sense to do via conditionally compiled files depending on the EnableRegexGenerator property instead.
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 fine with removing "it" - what's "it" though, just the constant or that entire target? That is, is that target there just to add that constant?
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 really see a scenario for this define or the target, I'd vote to remove them.
I can simplify the targets file (and it has to be done anyways), but I took another look at this, and I'm not sure whether regex is even required here. The pattern is I can find at least one identical usage in reference source, but this file is not in this repository, so at least some use seems to be in outside packages. Thoughts? |
I was thinking maybe this is for strings containing an embedded keyboard shortcut, eg @DustinCampbell perhaps you know about DesignerVerbs and what this might be for? |
I'd be fine with merging as-is as the behavior is not changing.. |
...braries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerVerb.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: kasperk81 <83082615+kasperk81@users.noreply.github.com>
You've understood it correctly @danmoseley. The |
@DustinCampbell to be clear then, the code could/should simply be |
For clarity, broken because:
|
I was thinking of both. Although it's so broken for that purpose one wonders how it could be. It's not the first time we look at some dusty corner of old code and it's not clear why something is some way. If @DustinCampbell (from Winforms/designer world) thinks it's OK to just replace & with '' then I suggest we do that. We have months to discover if that breaks something. |
I can't believe it took me this long to spot the problem with this: it fails if the ampersand is used "for itself" - If the text is (or should be) |
Would be good to get sign off from memebers of @dotnet/area-infrastructure-libraries for this PR. |
@joperezr @safern @carlossanlop - any thoughts here? I think this is just waiting for sign off from the libraries infrastructure team. |
I will take a look at this today. Apologies for missing the previous notification. |
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.
Left two small comments, but other than that this seems ready to go from my side. Thanks a lot @Clockwork-Muse for your patience and work on this!
Pushed changes as requested by @joperezr . Currently, this PR performs no behavioral changes, simply switching to the regex generator. However, there are still questions about what the correct behavior should be, and whether regex is even required in this situation. Should I open an issue to have someone look at that? |
Sure. |
Error just seems to be a build timeout? |
Indeed. @dotnet/dnceng can you make anything of this? I can't find any more info
|
@danmoseley We'll take all look. |
This looks like it happened at one of the times where the os.1200.amd64.open queue was super backed up and had to be purged. |
It's definitely this, turning off core dumps in runtime unblocked it because System.Runtime.InteropServices test was just spending hours uploading dumps on every machine. |
That makes sense. I created an issue to track the investigation here https://github.com/dotnet/core-eng/issues/15567 but I guess we can close it in this situation. |
Thank you @lpatalas @adiaaida |
On main, the output item type has changed for the dll generator. I'm assuming I should change things to match? |
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.
The changes in ComponentModel LGTM.
@dotnet/area-infrastructure-libraries - I don't see an approval there. Is everyone OK with the infra changes in this PR?
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.
Infra related changes look good to me.
Added generator to source library, not to tests (no tests found)