-
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
Address feedback from config binding gen PR to improve enum parsing #89952
Conversation
Tagging subscribers to this area: @dotnet/area-extensions-configuration |
@@ -128,7 +137,7 @@ private static bool IsValidRootConfigType(ITypeSymbol? type) | |||
{ | |||
ParsableFromStringSpec stringParsableSpec = new(type) { StringParsableTypeKind = specialTypeKind }; | |||
|
|||
if (stringParsableSpec.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue) | |||
if (stringParsableSpec.StringParsableTypeKind != StringParsableTypeKind.AssignFromSectionValue && stringParsableSpec.StringParsableTypeKind != StringParsableTypeKind.Enum) |
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'd re-write this as
if (stringParsableSpec.StringParsableTypeKind != StringParsableTypeKind.AssignFromSectionValue && stringParsableSpec.StringParsableTypeKind != StringParsableTypeKind.Enum) | |
if (specialTypeKind is StringParsableTypeKind.Enum) | |
{ | |
_sourceGenSpec.EmitEnumParseMethod = true; | |
} | |
else if (specialTypeKind is not StringParsableTypeKind.AssignFromSectionValue) | |
{ | |
_sourceGenSpec.PrimitivesForHelperGen.Add(stringParsableSpec); | |
} |
foreach (var typeSymbol in _createdSpecs.Keys) | ||
{ | ||
if (IsEnum(typeSymbol)) | ||
{ | ||
_sourceGenSpec.EmitEnumParseMethod = true; | ||
break; | ||
} | ||
} | ||
|
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.
Shouldn't need this given the suggestion below.
@pedrobsaila, let's go with checking for the right method in the parser - #89823 (comment). We could also address #89879 in this PR. |
@pedrobsaila apologies for my delayed response. Could you pls resolve merge conflicts here? |
@@ -108,6 +110,10 @@ public KnownTypeSymbols(CSharpCompilation compilation) | |||
IReadOnlyList_Unbound = compilation.GetBestTypeByMetadataName(typeof(IReadOnlyList<>))?.ConstructUnboundGenericType(); | |||
IReadOnlySet_Unbound = compilation.GetBestTypeByMetadataName("System.Collections.Generic.IReadOnlySet`1")?.ConstructUnboundGenericType(); | |||
ISet_Unbound = ISet?.ConstructUnboundGenericType(); | |||
|
|||
// needed to be able to know if a member exist inside the compilation unit | |||
Enum = compilation.GetBestTypeByMetadataName(typeof(Enum)); |
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.
Use the overload taking a SpecialType
(i.e. SpecialType.System_Enum
). All the special types are guaranteed to be in the input compilation.
@@ -54,6 +54,8 @@ internal sealed record KnownTypeSymbols | |||
public INamedTypeSymbol? ISet_Unbound { get; } | |||
public INamedTypeSymbol? ISet { get; } | |||
public INamedTypeSymbol? List { get; } | |||
public INamedTypeSymbol? Enum { get; } |
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.
public INamedTypeSymbol? Enum { get; } | |
public INamedTypeSymbol Enum { get; } |
Per https://github.com/dotnet/runtime/pull/89952/files#r1307693295 the fetched value would not be null.
@@ -63,6 +63,8 @@ public Parser(SourceProductionContext context, KnownTypeSymbols typeSymbols, Imm | |||
} | |||
} | |||
|
|||
_sourceGenSpec.EmitThrowIfNullMethod = !_typeSymbols.ArgumentNullException.GetMembers("ThrowIfNull").IsEmpty; |
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.
_sourceGenSpec.EmitThrowIfNullMethod = !_typeSymbols.ArgumentNullException.GetMembers("ThrowIfNull").IsEmpty; | |
_sourceGenSpec.EmitThrowIfNullMethod = _typeSymbols.ArgumentNullException?.GetMembers("ThrowIfNull").IsEmpty is false; |
The symbol could be null; avoid a null-ref exception.
@@ -0,0 +1,243 @@ | |||
// <auto-generated/> |
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.
Thanks for adding the net462
variants. Could we refactor to the following structure?
> baselines
> netcoreapp
> foo.generated.txt
> net462
> foo.generated.txt
I'd actually suggest making a preliminary PR doing this. We'd need to remove the condition on [this line] so that the net462 tests would be included in automated runs. Doing this will reveal a bit of additional, tangential work needed to complete the effort.
Oof looks like merging #91180 reset your rebase effort. If you take another stab, I'll be sure to check if this PR is merge-ready & queue it up first if so. |
{ | ||
string path = extType is ExtensionClassType.None |
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.
Please use a a preprocessor directive to determine the path
string path =
#if NETCOREAPP
...
#else
...
;
@@ -851,7 +852,7 @@ public async Task CollectionsFwk() | |||
{ | |||
string source = GetCollectionsSource(); | |||
|
|||
await VerifyAgainstBaselineUsingFile("Collections.net462.generated.txt", source, assessDiagnostics: (d) => |
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.
Per f5a2abc#r1321885499, please revert the changes to these invocations.
@@ -44,10 +93,8 @@ | |||
</ItemGroup> | |||
|
|||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'"> | |||
<Content Include="Baselines\*.generated.txt; |
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.
Please revert back to partitioning the baselines based on the binder ext. type. This is helpful when working issues specific to a particular binder.
@@ -63,7 +63,7 @@ public Parser(SourceProductionContext context, KnownTypeSymbols typeSymbols, Imm | |||
} | |||
} | |||
|
|||
_sourceGenSpec.EmitThrowIfNullMethod = !_typeSymbols.ArgumentNullException.GetMembers("ThrowIfNull").IsEmpty; | |||
_sourceGenSpec.EmitThrowIfNullMethod = _typeSymbols.ArgumentNullException is not null && _typeSymbols.ArgumentNullException.GetMembers("ThrowIfNull").IsEmpty is 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.
_sourceGenSpec.EmitThrowIfNullMethod = _typeSymbols.ArgumentNullException?.GetMembers("ThrowIfNull").IsEmpty is false;
Also -- to be doubly sure, check that the method has the expected parameters.
@layomia can you check it please before the PR become stale again |
@pedrobsaila apologies for the delayed response, would it be possible to rebase your changes? Thanks! |
@pedrobsaila do you have a chance to resolve the merging conflicts? |
I'm on it. The code in main branch changed deeply, resolving conflict is not easy and will take some time |
@eiriktsarpalis @tarekgh ready for a new round of reviews |
...raries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs
Show resolved
Hide resolved
...raries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs
Show resolved
Hide resolved
src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs
Show resolved
Hide resolved
...raries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs
Outdated
Show resolved
Hide resolved
...ries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs
Show resolved
Hide resolved
...ries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs
Show resolved
Hide resolved
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'"> | ||
<Content Include="Baselines\*.generated.txt;Baselines\ConfigurationBinder\*.generated.txt;Baselines\OptionsBuilder\*.generated.txt;Baselines\ServiceCollection\*.generated.txt"> | ||
<ItemGroup> | ||
<Content Include="Baselines\net462\*.generated.txt; |
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.
Include just Baselines does not seem to work, the max I could do is this lightweight version :
<Content Include="Baselines\*\*\*.generated.txt;
Baselines\*\*.generated.txt;">
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.
You can use the syntax
Line 42 in c9b5dd4
<Content Include="Baselines\**\*"> |
@pedrobsaila thanks for getting this ready. I added a few questions if you can help with. otherwise LGTM. |
Baselines\netcoreapp\ConfigurationBinder\*.generated.txt; | ||
Baselines\netcoreapp\OptionsBuilder\*.generated.txt; | ||
Baselines\netcoreapp\ServiceCollection\*.generated.txt;"> | ||
<Content Include="Baselines\*\*\*.generated.txt; |
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 doesn't look right.
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.
seems right to me. There are 2 patterns of files :
Baselines\netcoreapp\OptionsBuilder\*.generated.txt
=> would matchBaselines\*\*\*.generated.txt
Baselines\netcoreapp\Primitives.generated.txt
=> would matchBaselines\*.generated.txt
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 we can copy the whole Baseline as I pointed out in #89952 (comment) that will be better I guess.
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.
Thanks @pedrobsaila, LGTM.
Fixes #89936
Fixes #89879
@layomia I addressed the follow-up fixes.