-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Fix config binder source gen for a sole read-only collection ctor param #131358
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -542,6 +542,40 @@ public record Options(string Name, {{collectionType}}<string> Values); | |
| AssertCanCreateAssemblyImage(result.OutputCompilation); | ||
| } | ||
|
|
||
| [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] | ||
| [InlineData("IReadOnlyList")] | ||
| [InlineData("IReadOnlyCollection")] | ||
| [InlineData("IReadOnlySet")] | ||
| [InlineData("IEnumerable")] | ||
| public async Task SoleReadOnlyCollectionConstructorParameterIsBindable(string collectionType) | ||
| { | ||
| // Regression test: a type whose only member is a non-bindable, read-only collection | ||
| // constructor parameter (no other bindable property) used to make the generator emit a | ||
| // call to an Initialize method that was never generated, producing CS0103 at compile time. | ||
| string source = $$""" | ||
| using Microsoft.Extensions.Configuration; | ||
| using System.Collections.Generic; | ||
|
|
||
| public class Program | ||
| { | ||
| public static void Main() | ||
| { | ||
| ConfigurationBuilder configurationBuilder = new(); | ||
| IConfiguration config = configurationBuilder.Build(); | ||
| Options options = config.Get<Options>(); | ||
| } | ||
| } | ||
|
|
||
| public record Options({{collectionType}}<string> Values); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two coverage gaps around this shape:
|
||
| """; | ||
|
|
||
| ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source, assemblyReferences: GetAssemblyRefsWithAdditional(typeof(ConfigurationBuilder), typeof(List<>))); | ||
| Assert.NotNull(result.GeneratedSource); | ||
| Assert.Empty(result.Diagnostics); | ||
|
|
||
| AssertCanCreateAssemblyImage(result.OutputCompilation); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The assertions stop at compile-clean plus a produced assembly image. Since this fixes a source generator vs reflection parity regression, consider also asserting runtime binding behavior: populate an in-memory configuration with a value for |
||
| } | ||
|
|
||
| [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] | ||
| public async Task ComplexReadOnlyListConstructorParameterIsBindable() | ||
| { | ||
|
|
||
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.
IEnumerable<string>may classify as a bindable member, in which caseHasBindableMembersis true and this input routes through the pre-existing path rather than the newly fixed one. It still passes and is harmless, but it may not actually exercise the regression. Worth confirming, or swapping in an element type or shape you have verified takes the new path.